##// END OF EJS Templates
Adds a "New issue" link on the global issue list (#6204)....
Jean-Philippe Lang -
r14963:b56f77322ac2
parent child
Show More
@@ -1,73 +1,81
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2016 Jean-Philippe Lang
4 # Copyright (C) 2006-2016 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 module RoutesHelper
20 module RoutesHelper
21
21
22 # Returns the path to project issues or to the cross-project
22 # Returns the path to project issues or to the cross-project
23 # issue list if project is nil
23 # issue list if project is nil
24 def _project_issues_path(project, *args)
24 def _project_issues_path(project, *args)
25 if project
25 if project
26 project_issues_path(project, *args)
26 project_issues_path(project, *args)
27 else
27 else
28 issues_path(*args)
28 issues_path(*args)
29 end
29 end
30 end
30 end
31
31
32 def _new_project_issue_path(project, *args)
33 if project
34 new_project_issue_path(project, *args)
35 else
36 new_issue_path(*args)
37 end
38 end
39
32 def _project_calendar_path(project, *args)
40 def _project_calendar_path(project, *args)
33 project ? project_calendar_path(project, *args) : issues_calendar_path(*args)
41 project ? project_calendar_path(project, *args) : issues_calendar_path(*args)
34 end
42 end
35
43
36 def _project_gantt_path(project, *args)
44 def _project_gantt_path(project, *args)
37 project ? project_gantt_path(project, *args) : issues_gantt_path(*args)
45 project ? project_gantt_path(project, *args) : issues_gantt_path(*args)
38 end
46 end
39
47
40 def _time_entries_path(project, issue, *args)
48 def _time_entries_path(project, issue, *args)
41 if issue
49 if issue
42 issue_time_entries_path(issue, *args)
50 issue_time_entries_path(issue, *args)
43 elsif project
51 elsif project
44 project_time_entries_path(project, *args)
52 project_time_entries_path(project, *args)
45 else
53 else
46 time_entries_path(*args)
54 time_entries_path(*args)
47 end
55 end
48 end
56 end
49
57
50 def _report_time_entries_path(project, issue, *args)
58 def _report_time_entries_path(project, issue, *args)
51 if issue
59 if issue
52 report_issue_time_entries_path(issue, *args)
60 report_issue_time_entries_path(issue, *args)
53 elsif project
61 elsif project
54 report_project_time_entries_path(project, *args)
62 report_project_time_entries_path(project, *args)
55 else
63 else
56 report_time_entries_path(*args)
64 report_time_entries_path(*args)
57 end
65 end
58 end
66 end
59
67
60 def _new_time_entry_path(project, issue, *args)
68 def _new_time_entry_path(project, issue, *args)
61 if issue
69 if issue
62 new_issue_time_entry_path(issue, *args)
70 new_issue_time_entry_path(issue, *args)
63 elsif project
71 elsif project
64 new_project_time_entry_path(project, *args)
72 new_project_time_entry_path(project, *args)
65 else
73 else
66 new_time_entry_path(*args)
74 new_time_entry_path(*args)
67 end
75 end
68 end
76 end
69
77
70 def board_path(board, *args)
78 def board_path(board, *args)
71 project_board_path(board.project, board, *args)
79 project_board_path(board.project, board, *args)
72 end
80 end
73 end
81 end
@@ -1,127 +1,127
1 <div class="contextual">
1 <div class="contextual">
2 <% if @project && User.current.allowed_to?(:add_issues, @project) && @project.trackers.any? %>
2 <% if User.current.allowed_to?(:add_issues, @project, :global => true) && (@project.nil? || @project.trackers.any?) %>
3 <%= link_to l(:label_issue_new), new_project_issue_path(@project), :class => 'icon icon-add new-issue' %>
3 <%= link_to l(:label_issue_new), _new_project_issue_path(@project), :class => 'icon icon-add new-issue' %>
4 <% end %>
4 <% end %>
5 </div>
5 </div>
6
6
7 <h2><%= @query.new_record? ? l(:label_issue_plural) : @query.name %></h2>
7 <h2><%= @query.new_record? ? l(:label_issue_plural) : @query.name %></h2>
8 <% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %>
8 <% html_title(@query.new_record? ? l(:label_issue_plural) : @query.name) %>
9
9
10 <%= form_tag({ :controller => 'issues', :action => 'index', :project_id => @project },
10 <%= form_tag({ :controller => 'issues', :action => 'index', :project_id => @project },
11 :method => :get, :id => 'query_form') do %>
11 :method => :get, :id => 'query_form') do %>
12 <div id="query_form_with_buttons" class="hide-when-print">
12 <div id="query_form_with_buttons" class="hide-when-print">
13 <%= hidden_field_tag 'set_filter', '1' %>
13 <%= hidden_field_tag 'set_filter', '1' %>
14 <div id="query_form_content">
14 <div id="query_form_content">
15 <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
15 <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
16 <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
16 <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
17 <div style="<%= @query.new_record? ? "" : "display: none;" %>">
17 <div style="<%= @query.new_record? ? "" : "display: none;" %>">
18 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
18 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
19 </div>
19 </div>
20 </fieldset>
20 </fieldset>
21 <fieldset id="options" class="collapsible collapsed">
21 <fieldset id="options" class="collapsible collapsed">
22 <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
22 <legend onclick="toggleFieldset(this);"><%= l(:label_options) %></legend>
23 <div style="display: none;">
23 <div style="display: none;">
24 <table>
24 <table>
25 <tr>
25 <tr>
26 <td class="field"><%= l(:field_column_names) %></td>
26 <td class="field"><%= l(:field_column_names) %></td>
27 <td><%= render_query_columns_selection(@query) %></td>
27 <td><%= render_query_columns_selection(@query) %></td>
28 </tr>
28 </tr>
29 <tr>
29 <tr>
30 <td class="field"><label for='group_by'><%= l(:field_group_by) %></label></td>
30 <td class="field"><label for='group_by'><%= l(:field_group_by) %></label></td>
31 <td><%= select_tag('group_by',
31 <td><%= select_tag('group_by',
32 options_for_select(
32 options_for_select(
33 [[]] + @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]},
33 [[]] + @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]},
34 @query.group_by)
34 @query.group_by)
35 ) %></td>
35 ) %></td>
36 </tr>
36 </tr>
37 <tr>
37 <tr>
38 <td class="field"><%= l(:button_show) %></td>
38 <td class="field"><%= l(:button_show) %></td>
39 <td><%= available_block_columns_tags(@query) %></td>
39 <td><%= available_block_columns_tags(@query) %></td>
40 </tr>
40 </tr>
41 <tr>
41 <tr>
42 <td><%= l(:label_total_plural) %></td>
42 <td><%= l(:label_total_plural) %></td>
43 <td><%= available_totalable_columns_tags(@query) %></td>
43 <td><%= available_totalable_columns_tags(@query) %></td>
44 </tr>
44 </tr>
45 </table>
45 </table>
46 </div>
46 </div>
47 </fieldset>
47 </fieldset>
48 </div>
48 </div>
49 <p class="buttons">
49 <p class="buttons">
50 <%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %>
50 <%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %>
51 <%= link_to l(:button_clear), { :set_filter => 1, :project_id => @project }, :class => 'icon icon-reload' %>
51 <%= link_to l(:button_clear), { :set_filter => 1, :project_id => @project }, :class => 'icon icon-reload' %>
52 <% if @query.new_record? %>
52 <% if @query.new_record? %>
53 <% if User.current.allowed_to?(:save_queries, @project, :global => true) %>
53 <% if User.current.allowed_to?(:save_queries, @project, :global => true) %>
54 <%= link_to_function l(:button_save),
54 <%= link_to_function l(:button_save),
55 "$('#query_form').attr('action', '#{ @project ? new_project_query_path(@project) : new_query_path }').submit()",
55 "$('#query_form').attr('action', '#{ @project ? new_project_query_path(@project) : new_query_path }').submit()",
56 :class => 'icon icon-save' %>
56 :class => 'icon icon-save' %>
57 <% end %>
57 <% end %>
58 <% else %>
58 <% else %>
59 <% if @query.editable_by?(User.current) %>
59 <% if @query.editable_by?(User.current) %>
60 <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %>
60 <%= link_to l(:button_edit), edit_query_path(@query), :class => 'icon icon-edit' %>
61 <%= delete_link query_path(@query) %>
61 <%= delete_link query_path(@query) %>
62 <% end %>
62 <% end %>
63 <% end %>
63 <% end %>
64 </p>
64 </p>
65 </div>
65 </div>
66 <% end %>
66 <% end %>
67
67
68 <%= error_messages_for 'query' %>
68 <%= error_messages_for 'query' %>
69 <% if @query.valid? %>
69 <% if @query.valid? %>
70 <% if @issues.empty? %>
70 <% if @issues.empty? %>
71 <p class="nodata"><%= l(:label_no_data) %></p>
71 <p class="nodata"><%= l(:label_no_data) %></p>
72 <% else %>
72 <% else %>
73 <%= render_query_totals(@query) %>
73 <%= render_query_totals(@query) %>
74 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
74 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
75 <span class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></span>
75 <span class="pagination"><%= pagination_links_full @issue_pages, @issue_count %></span>
76 <% end %>
76 <% end %>
77
77
78 <% other_formats_links do |f| %>
78 <% other_formats_links do |f| %>
79 <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %>
79 <%= f.link_to 'Atom', :url => params.merge(:key => User.current.rss_key) %>
80 <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '350px'); return false;" %>
80 <%= f.link_to 'CSV', :url => params, :onclick => "showModal('csv-export-options', '350px'); return false;" %>
81 <%= f.link_to 'PDF', :url => params %>
81 <%= f.link_to 'PDF', :url => params %>
82 <% end %>
82 <% end %>
83
83
84 <div id="csv-export-options" style="display:none;">
84 <div id="csv-export-options" style="display:none;">
85 <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
85 <h3 class="title"><%= l(:label_export_options, :export_format => 'CSV') %></h3>
86 <%= form_tag(_project_issues_path(@project, :format => 'csv'), :method => :get, :id => 'csv-export-form') do %>
86 <%= form_tag(_project_issues_path(@project, :format => 'csv'), :method => :get, :id => 'csv-export-form') do %>
87 <%= query_as_hidden_field_tags(@query) %>
87 <%= query_as_hidden_field_tags(@query) %>
88 <%= hidden_field_tag 'sort', @sort_criteria.to_param, :id => nil %>
88 <%= hidden_field_tag 'sort', @sort_criteria.to_param, :id => nil %>
89 <p>
89 <p>
90 <label><%= radio_button_tag 'csv[columns]', '', true %> <%= l(:description_selected_columns) %></label><br />
90 <label><%= radio_button_tag 'csv[columns]', '', true %> <%= l(:description_selected_columns) %></label><br />
91 <label><%= radio_button_tag 'csv[columns]', 'all' %> <%= l(:description_all_columns) %></label>
91 <label><%= radio_button_tag 'csv[columns]', 'all' %> <%= l(:description_all_columns) %></label>
92 </p>
92 </p>
93 <p>
93 <p>
94 <label><%= check_box_tag 'csv[description]', '1', @query.has_column?(:description) %> <%= l(:field_description) %></label>
94 <label><%= check_box_tag 'csv[description]', '1', @query.has_column?(:description) %> <%= l(:field_description) %></label>
95 </p>
95 </p>
96 <% if @issue_count > Setting.issues_export_limit.to_i %>
96 <% if @issue_count > Setting.issues_export_limit.to_i %>
97 <p class="icon icon-warning">
97 <p class="icon icon-warning">
98 <%= l(:setting_issues_export_limit) %>: <%= Setting.issues_export_limit.to_i %>
98 <%= l(:setting_issues_export_limit) %>: <%= Setting.issues_export_limit.to_i %>
99 </p>
99 </p>
100 <% end %>
100 <% end %>
101 <p class="buttons">
101 <p class="buttons">
102 <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
102 <%= submit_tag l(:button_export), :name => nil, :onclick => "hideModal(this);" %>
103 <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
103 <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
104 </p>
104 </p>
105 <% end %>
105 <% end %>
106 </div>
106 </div>
107
107
108 <% end %>
108 <% end %>
109 <%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>
109 <%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>
110
110
111 <% content_for :sidebar do %>
111 <% content_for :sidebar do %>
112 <%= render :partial => 'issues/sidebar' %>
112 <%= render :partial => 'issues/sidebar' %>
113 <% end %>
113 <% end %>
114
114
115 <% content_for :header_tags do %>
115 <% content_for :header_tags do %>
116 <%= auto_discovery_link_tag(:atom,
116 <%= auto_discovery_link_tag(:atom,
117 {:query_id => @query, :format => 'atom',
117 {:query_id => @query, :format => 'atom',
118 :page => nil, :key => User.current.rss_key},
118 :page => nil, :key => User.current.rss_key},
119 :title => l(:label_issue_plural)) %>
119 :title => l(:label_issue_plural)) %>
120 <%= auto_discovery_link_tag(:atom,
120 <%= auto_discovery_link_tag(:atom,
121 {:controller => 'journals', :action => 'index',
121 {:controller => 'journals', :action => 'index',
122 :query_id => @query, :format => 'atom',
122 :query_id => @query, :format => 'atom',
123 :page => nil, :key => User.current.rss_key},
123 :page => nil, :key => User.current.rss_key},
124 :title => l(:label_changes_details)) %>
124 :title => l(:label_changes_details)) %>
125 <% end %>
125 <% end %>
126
126
127 <%= context_menu issues_context_menu_path %>
127 <%= context_menu issues_context_menu_path %>
@@ -1,4594 +1,4600
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
2 # Copyright (C) 2006-2016 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class IssuesControllerTest < ActionController::TestCase
20 class IssuesControllerTest < ActionController::TestCase
21 fixtures :projects,
21 fixtures :projects,
22 :users, :email_addresses, :user_preferences,
22 :users, :email_addresses, :user_preferences,
23 :roles,
23 :roles,
24 :members,
24 :members,
25 :member_roles,
25 :member_roles,
26 :issues,
26 :issues,
27 :issue_statuses,
27 :issue_statuses,
28 :issue_relations,
28 :issue_relations,
29 :versions,
29 :versions,
30 :trackers,
30 :trackers,
31 :projects_trackers,
31 :projects_trackers,
32 :issue_categories,
32 :issue_categories,
33 :enabled_modules,
33 :enabled_modules,
34 :enumerations,
34 :enumerations,
35 :attachments,
35 :attachments,
36 :workflows,
36 :workflows,
37 :custom_fields,
37 :custom_fields,
38 :custom_values,
38 :custom_values,
39 :custom_fields_projects,
39 :custom_fields_projects,
40 :custom_fields_trackers,
40 :custom_fields_trackers,
41 :time_entries,
41 :time_entries,
42 :journals,
42 :journals,
43 :journal_details,
43 :journal_details,
44 :queries,
44 :queries,
45 :repositories,
45 :repositories,
46 :changesets
46 :changesets
47
47
48 include Redmine::I18n
48 include Redmine::I18n
49
49
50 def setup
50 def setup
51 User.current = nil
51 User.current = nil
52 end
52 end
53
53
54 def test_index
54 def test_index
55 with_settings :default_language => "en" do
55 with_settings :default_language => "en" do
56 get :index
56 get :index
57 assert_response :success
57 assert_response :success
58 assert_template 'index'
58 assert_template 'index'
59 assert_not_nil assigns(:issues)
59 assert_not_nil assigns(:issues)
60 assert_nil assigns(:project)
60 assert_nil assigns(:project)
61
61
62 # links to visible issues
62 # links to visible issues
63 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
63 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
64 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
64 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
65 # private projects hidden
65 # private projects hidden
66 assert_select 'a[href="/issues/6"]', 0
66 assert_select 'a[href="/issues/6"]', 0
67 assert_select 'a[href="/issues/4"]', 0
67 assert_select 'a[href="/issues/4"]', 0
68 # project column
68 # project column
69 assert_select 'th', :text => /Project/
69 assert_select 'th', :text => /Project/
70 end
70 end
71 end
71 end
72
72
73 def test_index_should_not_list_issues_when_module_disabled
73 def test_index_should_not_list_issues_when_module_disabled
74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
75 get :index
75 get :index
76 assert_response :success
76 assert_response :success
77 assert_template 'index'
77 assert_template 'index'
78 assert_not_nil assigns(:issues)
78 assert_not_nil assigns(:issues)
79 assert_nil assigns(:project)
79 assert_nil assigns(:project)
80
80
81 assert_select 'a[href="/issues/1"]', 0
81 assert_select 'a[href="/issues/1"]', 0
82 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
82 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
83 end
83 end
84
84
85 def test_index_should_list_visible_issues_only
85 def test_index_should_list_visible_issues_only
86 get :index, :per_page => 100
86 get :index, :per_page => 100
87 assert_response :success
87 assert_response :success
88 assert_not_nil assigns(:issues)
88 assert_not_nil assigns(:issues)
89 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
89 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
90 end
90 end
91
91
92 def test_index_with_project
92 def test_index_with_project
93 Setting.display_subprojects_issues = 0
93 Setting.display_subprojects_issues = 0
94 get :index, :project_id => 1
94 get :index, :project_id => 1
95 assert_response :success
95 assert_response :success
96 assert_template 'index'
96 assert_template 'index'
97 assert_not_nil assigns(:issues)
97 assert_not_nil assigns(:issues)
98
98
99 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
99 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
100 assert_select 'a[href="/issues/5"]', 0
100 assert_select 'a[href="/issues/5"]', 0
101 end
101 end
102
102
103 def test_index_with_project_and_subprojects
103 def test_index_with_project_and_subprojects
104 Setting.display_subprojects_issues = 1
104 Setting.display_subprojects_issues = 1
105 get :index, :project_id => 1
105 get :index, :project_id => 1
106 assert_response :success
106 assert_response :success
107 assert_template 'index'
107 assert_template 'index'
108 assert_not_nil assigns(:issues)
108 assert_not_nil assigns(:issues)
109
109
110 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
110 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
111 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
111 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
112 assert_select 'a[href="/issues/6"]', 0
112 assert_select 'a[href="/issues/6"]', 0
113 end
113 end
114
114
115 def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
115 def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
116 @request.session[:user_id] = 2
116 @request.session[:user_id] = 2
117 Setting.display_subprojects_issues = 1
117 Setting.display_subprojects_issues = 1
118 get :index, :project_id => 1
118 get :index, :project_id => 1
119 assert_response :success
119 assert_response :success
120 assert_template 'index'
120 assert_template 'index'
121 assert_not_nil assigns(:issues)
121 assert_not_nil assigns(:issues)
122
122
123 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
123 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
124 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
124 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
125 assert_select 'a[href="/issues/6"]', :text => /Issue of a private subproject/
125 assert_select 'a[href="/issues/6"]', :text => /Issue of a private subproject/
126 end
126 end
127
127
128 def test_index_with_project_and_default_filter
128 def test_index_with_project_and_default_filter
129 get :index, :project_id => 1, :set_filter => 1
129 get :index, :project_id => 1, :set_filter => 1
130 assert_response :success
130 assert_response :success
131 assert_template 'index'
131 assert_template 'index'
132 assert_not_nil assigns(:issues)
132 assert_not_nil assigns(:issues)
133
133
134 query = assigns(:query)
134 query = assigns(:query)
135 assert_not_nil query
135 assert_not_nil query
136 # default filter
136 # default filter
137 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
137 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
138 end
138 end
139
139
140 def test_index_with_project_and_filter
140 def test_index_with_project_and_filter
141 get :index, :project_id => 1, :set_filter => 1,
141 get :index, :project_id => 1, :set_filter => 1,
142 :f => ['tracker_id'],
142 :f => ['tracker_id'],
143 :op => {'tracker_id' => '='},
143 :op => {'tracker_id' => '='},
144 :v => {'tracker_id' => ['1']}
144 :v => {'tracker_id' => ['1']}
145 assert_response :success
145 assert_response :success
146 assert_template 'index'
146 assert_template 'index'
147 assert_not_nil assigns(:issues)
147 assert_not_nil assigns(:issues)
148
148
149 query = assigns(:query)
149 query = assigns(:query)
150 assert_not_nil query
150 assert_not_nil query
151 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
151 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
152 end
152 end
153
153
154 def test_index_with_short_filters
154 def test_index_with_short_filters
155 to_test = {
155 to_test = {
156 'status_id' => {
156 'status_id' => {
157 'o' => { :op => 'o', :values => [''] },
157 'o' => { :op => 'o', :values => [''] },
158 'c' => { :op => 'c', :values => [''] },
158 'c' => { :op => 'c', :values => [''] },
159 '7' => { :op => '=', :values => ['7'] },
159 '7' => { :op => '=', :values => ['7'] },
160 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
160 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
161 '=7' => { :op => '=', :values => ['7'] },
161 '=7' => { :op => '=', :values => ['7'] },
162 '!3' => { :op => '!', :values => ['3'] },
162 '!3' => { :op => '!', :values => ['3'] },
163 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
163 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
164 'subject' => {
164 'subject' => {
165 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
165 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
166 'o' => { :op => '=', :values => ['o'] },
166 'o' => { :op => '=', :values => ['o'] },
167 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
167 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
168 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
168 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
169 'tracker_id' => {
169 'tracker_id' => {
170 '3' => { :op => '=', :values => ['3'] },
170 '3' => { :op => '=', :values => ['3'] },
171 '=3' => { :op => '=', :values => ['3'] }},
171 '=3' => { :op => '=', :values => ['3'] }},
172 'start_date' => {
172 'start_date' => {
173 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
173 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
174 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
174 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
175 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
175 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
176 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
176 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
177 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
177 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
178 '<t+2' => { :op => '<t+', :values => ['2'] },
178 '<t+2' => { :op => '<t+', :values => ['2'] },
179 '>t+2' => { :op => '>t+', :values => ['2'] },
179 '>t+2' => { :op => '>t+', :values => ['2'] },
180 't+2' => { :op => 't+', :values => ['2'] },
180 't+2' => { :op => 't+', :values => ['2'] },
181 't' => { :op => 't', :values => [''] },
181 't' => { :op => 't', :values => [''] },
182 'w' => { :op => 'w', :values => [''] },
182 'w' => { :op => 'w', :values => [''] },
183 '>t-2' => { :op => '>t-', :values => ['2'] },
183 '>t-2' => { :op => '>t-', :values => ['2'] },
184 '<t-2' => { :op => '<t-', :values => ['2'] },
184 '<t-2' => { :op => '<t-', :values => ['2'] },
185 't-2' => { :op => 't-', :values => ['2'] }},
185 't-2' => { :op => 't-', :values => ['2'] }},
186 'created_on' => {
186 'created_on' => {
187 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
187 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
188 '<t-2' => { :op => '<t-', :values => ['2'] },
188 '<t-2' => { :op => '<t-', :values => ['2'] },
189 '>t-2' => { :op => '>t-', :values => ['2'] },
189 '>t-2' => { :op => '>t-', :values => ['2'] },
190 't-2' => { :op => 't-', :values => ['2'] }},
190 't-2' => { :op => 't-', :values => ['2'] }},
191 'cf_1' => {
191 'cf_1' => {
192 'c' => { :op => '=', :values => ['c'] },
192 'c' => { :op => '=', :values => ['c'] },
193 '!c' => { :op => '!', :values => ['c'] },
193 '!c' => { :op => '!', :values => ['c'] },
194 '!*' => { :op => '!*', :values => [''] },
194 '!*' => { :op => '!*', :values => [''] },
195 '*' => { :op => '*', :values => [''] }},
195 '*' => { :op => '*', :values => [''] }},
196 'estimated_hours' => {
196 'estimated_hours' => {
197 '=13.4' => { :op => '=', :values => ['13.4'] },
197 '=13.4' => { :op => '=', :values => ['13.4'] },
198 '>=45' => { :op => '>=', :values => ['45'] },
198 '>=45' => { :op => '>=', :values => ['45'] },
199 '<=125' => { :op => '<=', :values => ['125'] },
199 '<=125' => { :op => '<=', :values => ['125'] },
200 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
200 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
201 '!*' => { :op => '!*', :values => [''] },
201 '!*' => { :op => '!*', :values => [''] },
202 '*' => { :op => '*', :values => [''] }}
202 '*' => { :op => '*', :values => [''] }}
203 }
203 }
204
204
205 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
205 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
206
206
207 to_test.each do |field, expression_and_expected|
207 to_test.each do |field, expression_and_expected|
208 expression_and_expected.each do |filter_expression, expected|
208 expression_and_expected.each do |filter_expression, expected|
209
209
210 get :index, :set_filter => 1, field => filter_expression
210 get :index, :set_filter => 1, field => filter_expression
211
211
212 assert_response :success
212 assert_response :success
213 assert_template 'index'
213 assert_template 'index'
214 assert_not_nil assigns(:issues)
214 assert_not_nil assigns(:issues)
215
215
216 query = assigns(:query)
216 query = assigns(:query)
217 assert_not_nil query
217 assert_not_nil query
218 assert query.has_filter?(field)
218 assert query.has_filter?(field)
219 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
219 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
220 end
220 end
221 end
221 end
222 end
222 end
223
223
224 def test_index_with_project_and_empty_filters
224 def test_index_with_project_and_empty_filters
225 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
225 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
226 assert_response :success
226 assert_response :success
227 assert_template 'index'
227 assert_template 'index'
228 assert_not_nil assigns(:issues)
228 assert_not_nil assigns(:issues)
229
229
230 query = assigns(:query)
230 query = assigns(:query)
231 assert_not_nil query
231 assert_not_nil query
232 # no filter
232 # no filter
233 assert_equal({}, query.filters)
233 assert_equal({}, query.filters)
234 end
234 end
235
235
236 def test_index_with_project_custom_field_filter
236 def test_index_with_project_custom_field_filter
237 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
237 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
238 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
238 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
239 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
239 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
240 filter_name = "project.cf_#{field.id}"
240 filter_name = "project.cf_#{field.id}"
241 @request.session[:user_id] = 1
241 @request.session[:user_id] = 1
242
242
243 get :index, :set_filter => 1,
243 get :index, :set_filter => 1,
244 :f => [filter_name],
244 :f => [filter_name],
245 :op => {filter_name => '='},
245 :op => {filter_name => '='},
246 :v => {filter_name => ['Foo']}
246 :v => {filter_name => ['Foo']}
247 assert_response :success
247 assert_response :success
248 assert_template 'index'
248 assert_template 'index'
249 assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
249 assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
250 end
250 end
251
251
252 def test_index_with_query
252 def test_index_with_query
253 get :index, :project_id => 1, :query_id => 5
253 get :index, :project_id => 1, :query_id => 5
254 assert_response :success
254 assert_response :success
255 assert_template 'index'
255 assert_template 'index'
256 assert_not_nil assigns(:issues)
256 assert_not_nil assigns(:issues)
257 assert_nil assigns(:issue_count_by_group)
257 assert_nil assigns(:issue_count_by_group)
258 end
258 end
259
259
260 def test_index_with_query_grouped_by_tracker
260 def test_index_with_query_grouped_by_tracker
261 get :index, :project_id => 1, :query_id => 6
261 get :index, :project_id => 1, :query_id => 6
262 assert_response :success
262 assert_response :success
263 assert_template 'index'
263 assert_template 'index'
264 assert_not_nil assigns(:issues)
264 assert_not_nil assigns(:issues)
265 assert_not_nil assigns(:issue_count_by_group)
265 assert_not_nil assigns(:issue_count_by_group)
266 end
266 end
267
267
268 def test_index_with_query_grouped_and_sorted_by_category
268 def test_index_with_query_grouped_and_sorted_by_category
269 get :index, :project_id => 1, :set_filter => 1, :group_by => "category", :sort => "category"
269 get :index, :project_id => 1, :set_filter => 1, :group_by => "category", :sort => "category"
270 assert_response :success
270 assert_response :success
271 assert_template 'index'
271 assert_template 'index'
272 assert_not_nil assigns(:issues)
272 assert_not_nil assigns(:issues)
273 assert_not_nil assigns(:issue_count_by_group)
273 assert_not_nil assigns(:issue_count_by_group)
274 end
274 end
275
275
276 def test_index_with_query_grouped_by_list_custom_field
276 def test_index_with_query_grouped_by_list_custom_field
277 get :index, :project_id => 1, :query_id => 9
277 get :index, :project_id => 1, :query_id => 9
278 assert_response :success
278 assert_response :success
279 assert_template 'index'
279 assert_template 'index'
280 assert_not_nil assigns(:issues)
280 assert_not_nil assigns(:issues)
281 assert_not_nil assigns(:issue_count_by_group)
281 assert_not_nil assigns(:issue_count_by_group)
282 end
282 end
283
283
284 def test_index_with_query_grouped_by_key_value_custom_field
284 def test_index_with_query_grouped_by_key_value_custom_field
285 cf = IssueCustomField.create!(:name => 'Key', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'enumeration')
285 cf = IssueCustomField.create!(:name => 'Key', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'enumeration')
286 cf.enumerations << valueb = CustomFieldEnumeration.new(:name => 'Value B', :position => 1)
286 cf.enumerations << valueb = CustomFieldEnumeration.new(:name => 'Value B', :position => 1)
287 cf.enumerations << valuea = CustomFieldEnumeration.new(:name => 'Value A', :position => 2)
287 cf.enumerations << valuea = CustomFieldEnumeration.new(:name => 'Value A', :position => 2)
288 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => valueb.id)
288 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => valueb.id)
289 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => valueb.id)
289 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => valueb.id)
290 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => valuea.id)
290 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => valuea.id)
291 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
291 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
292
292
293 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
293 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
294 assert_response :success
294 assert_response :success
295 assert_template 'index'
295 assert_template 'index'
296 assert_not_nil assigns(:issues)
296 assert_not_nil assigns(:issues)
297 assert_not_nil assigns(:issue_count_by_group)
297 assert_not_nil assigns(:issue_count_by_group)
298
298
299 assert_select 'tr.group', 3
299 assert_select 'tr.group', 3
300 assert_select 'tr.group' do
300 assert_select 'tr.group' do
301 assert_select 'span.name', :text => 'Value B'
301 assert_select 'span.name', :text => 'Value B'
302 assert_select 'span.count', :text => '2'
302 assert_select 'span.count', :text => '2'
303 end
303 end
304 assert_select 'tr.group' do
304 assert_select 'tr.group' do
305 assert_select 'span.name', :text => 'Value A'
305 assert_select 'span.name', :text => 'Value A'
306 assert_select 'span.count', :text => '1'
306 assert_select 'span.count', :text => '1'
307 end
307 end
308 end
308 end
309
309
310 def test_index_with_query_grouped_by_user_custom_field
310 def test_index_with_query_grouped_by_user_custom_field
311 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
311 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
312 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
312 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
313 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
313 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
314 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
314 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
315 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
315 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
316
316
317 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
317 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
318 assert_response :success
318 assert_response :success
319
319
320 assert_select 'tr.group', 3
320 assert_select 'tr.group', 3
321 assert_select 'tr.group' do
321 assert_select 'tr.group' do
322 assert_select 'a', :text => 'John Smith'
322 assert_select 'a', :text => 'John Smith'
323 assert_select 'span.count', :text => '1'
323 assert_select 'span.count', :text => '1'
324 end
324 end
325 assert_select 'tr.group' do
325 assert_select 'tr.group' do
326 assert_select 'a', :text => 'Dave Lopper'
326 assert_select 'a', :text => 'Dave Lopper'
327 assert_select 'span.count', :text => '2'
327 assert_select 'span.count', :text => '2'
328 end
328 end
329 end
329 end
330
330
331 def test_index_grouped_by_boolean_custom_field_should_distinguish_blank_and_false_values
331 def test_index_grouped_by_boolean_custom_field_should_distinguish_blank_and_false_values
332 cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool')
332 cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool')
333 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '1')
333 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '1')
334 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
334 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
335 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '')
335 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '')
336
336
337 with_settings :default_language => 'en' do
337 with_settings :default_language => 'en' do
338 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
338 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
339 assert_response :success
339 assert_response :success
340 end
340 end
341
341
342 assert_select 'tr.group', 3
342 assert_select 'tr.group', 3
343 assert_select 'tr.group', :text => /Yes/
343 assert_select 'tr.group', :text => /Yes/
344 assert_select 'tr.group', :text => /No/
344 assert_select 'tr.group', :text => /No/
345 assert_select 'tr.group', :text => /blank/
345 assert_select 'tr.group', :text => /blank/
346 end
346 end
347
347
348 def test_index_grouped_by_boolean_custom_field_with_false_group_in_first_position_should_show_the_group
348 def test_index_grouped_by_boolean_custom_field_with_false_group_in_first_position_should_show_the_group
349 cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool', :is_filter => true)
349 cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool', :is_filter => true)
350 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '0')
350 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '0')
351 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
351 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
352
352
353 with_settings :default_language => 'en' do
353 with_settings :default_language => 'en' do
354 get :index, :project_id => 1, :set_filter => 1, "cf_#{cf.id}" => "*", :group_by => "cf_#{cf.id}"
354 get :index, :project_id => 1, :set_filter => 1, "cf_#{cf.id}" => "*", :group_by => "cf_#{cf.id}"
355 assert_response :success
355 assert_response :success
356 assert_equal [1, 2], assigns(:issues).map(&:id).sort
356 assert_equal [1, 2], assigns(:issues).map(&:id).sort
357 end
357 end
358
358
359 assert_select 'tr.group', 1
359 assert_select 'tr.group', 1
360 assert_select 'tr.group', :text => /No/
360 assert_select 'tr.group', :text => /No/
361 end
361 end
362
362
363 def test_index_with_query_grouped_by_tracker_in_normal_order
363 def test_index_with_query_grouped_by_tracker_in_normal_order
364 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
364 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
365
365
366 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
366 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
367 assert_response :success
367 assert_response :success
368
368
369 trackers = assigns(:issues).map(&:tracker).uniq
369 trackers = assigns(:issues).map(&:tracker).uniq
370 assert_equal [1, 2, 3], trackers.map(&:id)
370 assert_equal [1, 2, 3], trackers.map(&:id)
371 end
371 end
372
372
373 def test_index_with_query_grouped_by_tracker_in_reverse_order
373 def test_index_with_query_grouped_by_tracker_in_reverse_order
374 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
374 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
375
375
376 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
376 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
377 assert_response :success
377 assert_response :success
378
378
379 trackers = assigns(:issues).map(&:tracker).uniq
379 trackers = assigns(:issues).map(&:tracker).uniq
380 assert_equal [3, 2, 1], trackers.map(&:id)
380 assert_equal [3, 2, 1], trackers.map(&:id)
381 end
381 end
382
382
383 def test_index_with_query_id_and_project_id_should_set_session_query
383 def test_index_with_query_id_and_project_id_should_set_session_query
384 get :index, :project_id => 1, :query_id => 4
384 get :index, :project_id => 1, :query_id => 4
385 assert_response :success
385 assert_response :success
386 assert_kind_of Hash, session[:query]
386 assert_kind_of Hash, session[:query]
387 assert_equal 4, session[:query][:id]
387 assert_equal 4, session[:query][:id]
388 assert_equal 1, session[:query][:project_id]
388 assert_equal 1, session[:query][:project_id]
389 end
389 end
390
390
391 def test_index_with_invalid_query_id_should_respond_404
391 def test_index_with_invalid_query_id_should_respond_404
392 get :index, :project_id => 1, :query_id => 999
392 get :index, :project_id => 1, :query_id => 999
393 assert_response 404
393 assert_response 404
394 end
394 end
395
395
396 def test_index_with_cross_project_query_in_session_should_show_project_issues
396 def test_index_with_cross_project_query_in_session_should_show_project_issues
397 q = IssueQuery.create!(:name => "test", :user_id => 2, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
397 q = IssueQuery.create!(:name => "test", :user_id => 2, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
398 @request.session[:query] = {:id => q.id, :project_id => 1}
398 @request.session[:query] = {:id => q.id, :project_id => 1}
399
399
400 with_settings :display_subprojects_issues => '0' do
400 with_settings :display_subprojects_issues => '0' do
401 get :index, :project_id => 1
401 get :index, :project_id => 1
402 end
402 end
403 assert_response :success
403 assert_response :success
404 assert_not_nil assigns(:query)
404 assert_not_nil assigns(:query)
405 assert_equal q.id, assigns(:query).id
405 assert_equal q.id, assigns(:query).id
406 assert_equal 1, assigns(:query).project_id
406 assert_equal 1, assigns(:query).project_id
407 assert_equal [1], assigns(:issues).map(&:project_id).uniq
407 assert_equal [1], assigns(:issues).map(&:project_id).uniq
408 end
408 end
409
409
410 def test_private_query_should_not_be_available_to_other_users
410 def test_private_query_should_not_be_available_to_other_users
411 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
411 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
412 @request.session[:user_id] = 3
412 @request.session[:user_id] = 3
413
413
414 get :index, :query_id => q.id
414 get :index, :query_id => q.id
415 assert_response 403
415 assert_response 403
416 end
416 end
417
417
418 def test_private_query_should_be_available_to_its_user
418 def test_private_query_should_be_available_to_its_user
419 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
419 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
420 @request.session[:user_id] = 2
420 @request.session[:user_id] = 2
421
421
422 get :index, :query_id => q.id
422 get :index, :query_id => q.id
423 assert_response :success
423 assert_response :success
424 end
424 end
425
425
426 def test_public_query_should_be_available_to_other_users
426 def test_public_query_should_be_available_to_other_users
427 q = IssueQuery.create!(:name => "public", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil)
427 q = IssueQuery.create!(:name => "public", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil)
428 @request.session[:user_id] = 3
428 @request.session[:user_id] = 3
429
429
430 get :index, :query_id => q.id
430 get :index, :query_id => q.id
431 assert_response :success
431 assert_response :success
432 end
432 end
433
433
434 def test_index_should_omit_page_param_in_export_links
434 def test_index_should_omit_page_param_in_export_links
435 get :index, :page => 2
435 get :index, :page => 2
436 assert_response :success
436 assert_response :success
437 assert_select 'a.atom[href="/issues.atom"]'
437 assert_select 'a.atom[href="/issues.atom"]'
438 assert_select 'a.csv[href="/issues.csv"]'
438 assert_select 'a.csv[href="/issues.csv"]'
439 assert_select 'a.pdf[href="/issues.pdf"]'
439 assert_select 'a.pdf[href="/issues.pdf"]'
440 assert_select 'form#csv-export-form[action="/issues.csv"]'
440 assert_select 'form#csv-export-form[action="/issues.csv"]'
441 end
441 end
442
442
443 def test_index_should_not_warn_when_not_exceeding_export_limit
443 def test_index_should_not_warn_when_not_exceeding_export_limit
444 with_settings :issues_export_limit => 200 do
444 with_settings :issues_export_limit => 200 do
445 get :index
445 get :index
446 assert_select '#csv-export-options p.icon-warning', 0
446 assert_select '#csv-export-options p.icon-warning', 0
447 end
447 end
448 end
448 end
449
449
450 def test_index_should_warn_when_exceeding_export_limit
450 def test_index_should_warn_when_exceeding_export_limit
451 with_settings :issues_export_limit => 2 do
451 with_settings :issues_export_limit => 2 do
452 get :index
452 get :index
453 assert_select '#csv-export-options p.icon-warning', :text => %r{limit: 2}
453 assert_select '#csv-export-options p.icon-warning', :text => %r{limit: 2}
454 end
454 end
455 end
455 end
456
456
457 def test_index_should_include_query_params_as_hidden_fields_in_csv_export_form
457 def test_index_should_include_query_params_as_hidden_fields_in_csv_export_form
458 get :index, :project_id => 1, :set_filter => "1", :tracker_id => "2", :sort => 'status', :c => ["status", "priority"]
458 get :index, :project_id => 1, :set_filter => "1", :tracker_id => "2", :sort => 'status', :c => ["status", "priority"]
459
459
460 assert_select '#csv-export-form[action=?]', '/projects/ecookbook/issues.csv'
460 assert_select '#csv-export-form[action=?]', '/projects/ecookbook/issues.csv'
461 assert_select '#csv-export-form[method=?]', 'get'
461 assert_select '#csv-export-form[method=?]', 'get'
462
462
463 assert_select '#csv-export-form' do
463 assert_select '#csv-export-form' do
464 assert_select 'input[name=?][value=?]', 'set_filter', '1'
464 assert_select 'input[name=?][value=?]', 'set_filter', '1'
465
465
466 assert_select 'input[name=?][value=?]', 'f[]', 'tracker_id'
466 assert_select 'input[name=?][value=?]', 'f[]', 'tracker_id'
467 assert_select 'input[name=?][value=?]', 'op[tracker_id]', '='
467 assert_select 'input[name=?][value=?]', 'op[tracker_id]', '='
468 assert_select 'input[name=?][value=?]', 'v[tracker_id][]', '2'
468 assert_select 'input[name=?][value=?]', 'v[tracker_id][]', '2'
469
469
470 assert_select 'input[name=?][value=?]', 'c[]', 'status'
470 assert_select 'input[name=?][value=?]', 'c[]', 'status'
471 assert_select 'input[name=?][value=?]', 'c[]', 'priority'
471 assert_select 'input[name=?][value=?]', 'c[]', 'priority'
472
472
473 assert_select 'input[name=?][value=?]', 'sort', 'status'
473 assert_select 'input[name=?][value=?]', 'sort', 'status'
474 end
474 end
475 end
475 end
476
476
477 def test_index_csv
477 def test_index_csv
478 get :index, :format => 'csv'
478 get :index, :format => 'csv'
479 assert_response :success
479 assert_response :success
480 assert_not_nil assigns(:issues)
480 assert_not_nil assigns(:issues)
481 assert_equal 'text/csv; header=present', @response.content_type
481 assert_equal 'text/csv; header=present', @response.content_type
482 assert @response.body.starts_with?("#,")
482 assert @response.body.starts_with?("#,")
483 lines = @response.body.chomp.split("\n")
483 lines = @response.body.chomp.split("\n")
484 assert_equal assigns(:query).columns.size, lines[0].split(',').size
484 assert_equal assigns(:query).columns.size, lines[0].split(',').size
485 end
485 end
486
486
487 def test_index_csv_with_project
487 def test_index_csv_with_project
488 get :index, :project_id => 1, :format => 'csv'
488 get :index, :project_id => 1, :format => 'csv'
489 assert_response :success
489 assert_response :success
490 assert_not_nil assigns(:issues)
490 assert_not_nil assigns(:issues)
491 assert_equal 'text/csv; header=present', @response.content_type
491 assert_equal 'text/csv; header=present', @response.content_type
492 end
492 end
493
493
494 def test_index_csv_with_description
494 def test_index_csv_with_description
495 Issue.generate!(:description => 'test_index_csv_with_description')
495 Issue.generate!(:description => 'test_index_csv_with_description')
496
496
497 with_settings :default_language => 'en' do
497 with_settings :default_language => 'en' do
498 get :index, :format => 'csv', :csv => {:description => '1'}
498 get :index, :format => 'csv', :csv => {:description => '1'}
499 assert_response :success
499 assert_response :success
500 assert_not_nil assigns(:issues)
500 assert_not_nil assigns(:issues)
501 end
501 end
502
502
503 assert_equal 'text/csv; header=present', response.content_type
503 assert_equal 'text/csv; header=present', response.content_type
504 headers = response.body.chomp.split("\n").first.split(',')
504 headers = response.body.chomp.split("\n").first.split(',')
505 assert_include 'Description', headers
505 assert_include 'Description', headers
506 assert_include 'test_index_csv_with_description', response.body
506 assert_include 'test_index_csv_with_description', response.body
507 end
507 end
508
508
509 def test_index_csv_with_spent_time_column
509 def test_index_csv_with_spent_time_column
510 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
510 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
511 TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
511 TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
512
512
513 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
513 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
514 assert_response :success
514 assert_response :success
515 assert_equal 'text/csv; header=present', @response.content_type
515 assert_equal 'text/csv; header=present', @response.content_type
516 lines = @response.body.chomp.split("\n")
516 lines = @response.body.chomp.split("\n")
517 assert_include "#{issue.id},#{issue.subject},7.33", lines
517 assert_include "#{issue.id},#{issue.subject},7.33", lines
518 end
518 end
519
519
520 def test_index_csv_with_all_columns
520 def test_index_csv_with_all_columns
521 get :index, :format => 'csv', :csv => {:columns => 'all'}
521 get :index, :format => 'csv', :csv => {:columns => 'all'}
522 assert_response :success
522 assert_response :success
523 assert_not_nil assigns(:issues)
523 assert_not_nil assigns(:issues)
524 assert_equal 'text/csv; header=present', @response.content_type
524 assert_equal 'text/csv; header=present', @response.content_type
525 assert_match /\A#,/, response.body
525 assert_match /\A#,/, response.body
526 lines = response.body.chomp.split("\n")
526 lines = response.body.chomp.split("\n")
527 assert_equal assigns(:query).available_inline_columns.size, lines[0].split(',').size
527 assert_equal assigns(:query).available_inline_columns.size, lines[0].split(',').size
528 end
528 end
529
529
530 def test_index_csv_with_multi_column_field
530 def test_index_csv_with_multi_column_field
531 CustomField.find(1).update_attribute :multiple, true
531 CustomField.find(1).update_attribute :multiple, true
532 issue = Issue.find(1)
532 issue = Issue.find(1)
533 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
533 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
534 issue.save!
534 issue.save!
535
535
536 get :index, :format => 'csv', :csv => {:columns => 'all'}
536 get :index, :format => 'csv', :csv => {:columns => 'all'}
537 assert_response :success
537 assert_response :success
538 lines = @response.body.chomp.split("\n")
538 lines = @response.body.chomp.split("\n")
539 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
539 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
540 end
540 end
541
541
542 def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator
542 def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator
543 field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float')
543 field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float')
544 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'})
544 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'})
545
545
546 with_settings :default_language => 'fr' do
546 with_settings :default_language => 'fr' do
547 get :index, :format => 'csv', :csv => {:columns => 'all'}
547 get :index, :format => 'csv', :csv => {:columns => 'all'}
548 assert_response :success
548 assert_response :success
549 issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s}
549 issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s}
550 assert_include '185,60', issue_line
550 assert_include '185,60', issue_line
551 end
551 end
552
552
553 with_settings :default_language => 'en' do
553 with_settings :default_language => 'en' do
554 get :index, :format => 'csv', :csv => {:columns => 'all'}
554 get :index, :format => 'csv', :csv => {:columns => 'all'}
555 assert_response :success
555 assert_response :success
556 issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s}
556 issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s}
557 assert_include '185.60', issue_line
557 assert_include '185.60', issue_line
558 end
558 end
559 end
559 end
560
560
561 def test_index_csv_should_fill_parent_column_with_parent_id
561 def test_index_csv_should_fill_parent_column_with_parent_id
562 Issue.delete_all
562 Issue.delete_all
563 parent = Issue.generate!
563 parent = Issue.generate!
564 child = Issue.generate!(:parent_issue_id => parent.id)
564 child = Issue.generate!(:parent_issue_id => parent.id)
565
565
566 with_settings :default_language => 'en' do
566 with_settings :default_language => 'en' do
567 get :index, :format => 'csv', :c => %w(parent)
567 get :index, :format => 'csv', :c => %w(parent)
568 end
568 end
569 lines = response.body.split("\n")
569 lines = response.body.split("\n")
570 assert_include "#{child.id},#{parent.id}", lines
570 assert_include "#{child.id},#{parent.id}", lines
571 end
571 end
572
572
573 def test_index_csv_big_5
573 def test_index_csv_big_5
574 with_settings :default_language => "zh-TW" do
574 with_settings :default_language => "zh-TW" do
575 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88".force_encoding('UTF-8')
575 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88".force_encoding('UTF-8')
576 str_big5 = "\xa4@\xa4\xeb".force_encoding('Big5')
576 str_big5 = "\xa4@\xa4\xeb".force_encoding('Big5')
577 issue = Issue.generate!(:subject => str_utf8)
577 issue = Issue.generate!(:subject => str_utf8)
578
578
579 get :index, :project_id => 1,
579 get :index, :project_id => 1,
580 :f => ['subject'],
580 :f => ['subject'],
581 :op => '=', :values => [str_utf8],
581 :op => '=', :values => [str_utf8],
582 :format => 'csv'
582 :format => 'csv'
583 assert_equal 'text/csv; header=present', @response.content_type
583 assert_equal 'text/csv; header=present', @response.content_type
584 lines = @response.body.chomp.split("\n")
584 lines = @response.body.chomp.split("\n")
585 header = lines[0]
585 header = lines[0]
586 status = "\xaa\xac\xbaA".force_encoding('Big5')
586 status = "\xaa\xac\xbaA".force_encoding('Big5')
587 assert_include status, header
587 assert_include status, header
588 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
588 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
589 assert_include str_big5, issue_line
589 assert_include str_big5, issue_line
590 end
590 end
591 end
591 end
592
592
593 def test_index_csv_cannot_convert_should_be_replaced_big_5
593 def test_index_csv_cannot_convert_should_be_replaced_big_5
594 with_settings :default_language => "zh-TW" do
594 with_settings :default_language => "zh-TW" do
595 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85".force_encoding('UTF-8')
595 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85".force_encoding('UTF-8')
596 issue = Issue.generate!(:subject => str_utf8)
596 issue = Issue.generate!(:subject => str_utf8)
597
597
598 get :index, :project_id => 1,
598 get :index, :project_id => 1,
599 :f => ['subject'],
599 :f => ['subject'],
600 :op => '=', :values => [str_utf8],
600 :op => '=', :values => [str_utf8],
601 :c => ['status', 'subject'],
601 :c => ['status', 'subject'],
602 :format => 'csv',
602 :format => 'csv',
603 :set_filter => 1
603 :set_filter => 1
604 assert_equal 'text/csv; header=present', @response.content_type
604 assert_equal 'text/csv; header=present', @response.content_type
605 lines = @response.body.chomp.split("\n")
605 lines = @response.body.chomp.split("\n")
606 header = lines[0]
606 header = lines[0]
607 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
607 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
608 s1 = "\xaa\xac\xbaA".force_encoding('Big5') # status
608 s1 = "\xaa\xac\xbaA".force_encoding('Big5') # status
609 assert header.include?(s1)
609 assert header.include?(s1)
610 s2 = issue_line.split(",")[2]
610 s2 = issue_line.split(",")[2]
611 s3 = "\xa5H?".force_encoding('Big5') # subject
611 s3 = "\xa5H?".force_encoding('Big5') # subject
612 assert_equal s3, s2
612 assert_equal s3, s2
613 end
613 end
614 end
614 end
615
615
616 def test_index_csv_tw
616 def test_index_csv_tw
617 with_settings :default_language => "zh-TW" do
617 with_settings :default_language => "zh-TW" do
618 str1 = "test_index_csv_tw"
618 str1 = "test_index_csv_tw"
619 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
619 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
620
620
621 get :index, :project_id => 1,
621 get :index, :project_id => 1,
622 :f => ['subject'],
622 :f => ['subject'],
623 :op => '=', :values => [str1],
623 :op => '=', :values => [str1],
624 :c => ['estimated_hours', 'subject'],
624 :c => ['estimated_hours', 'subject'],
625 :format => 'csv',
625 :format => 'csv',
626 :set_filter => 1
626 :set_filter => 1
627 assert_equal 'text/csv; header=present', @response.content_type
627 assert_equal 'text/csv; header=present', @response.content_type
628 lines = @response.body.chomp.split("\n")
628 lines = @response.body.chomp.split("\n")
629 assert_include "#{issue.id},1234.50,#{str1}", lines
629 assert_include "#{issue.id},1234.50,#{str1}", lines
630 end
630 end
631 end
631 end
632
632
633 def test_index_csv_fr
633 def test_index_csv_fr
634 with_settings :default_language => "fr" do
634 with_settings :default_language => "fr" do
635 str1 = "test_index_csv_fr"
635 str1 = "test_index_csv_fr"
636 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
636 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
637
637
638 get :index, :project_id => 1,
638 get :index, :project_id => 1,
639 :f => ['subject'],
639 :f => ['subject'],
640 :op => '=', :values => [str1],
640 :op => '=', :values => [str1],
641 :c => ['estimated_hours', 'subject'],
641 :c => ['estimated_hours', 'subject'],
642 :format => 'csv',
642 :format => 'csv',
643 :set_filter => 1
643 :set_filter => 1
644 assert_equal 'text/csv; header=present', @response.content_type
644 assert_equal 'text/csv; header=present', @response.content_type
645 lines = @response.body.chomp.split("\n")
645 lines = @response.body.chomp.split("\n")
646 assert_include "#{issue.id};1234,50;#{str1}", lines
646 assert_include "#{issue.id};1234,50;#{str1}", lines
647 end
647 end
648 end
648 end
649
649
650 def test_index_pdf
650 def test_index_pdf
651 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
651 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
652 with_settings :default_language => lang do
652 with_settings :default_language => lang do
653
653
654 get :index
654 get :index
655 assert_response :success
655 assert_response :success
656 assert_template 'index'
656 assert_template 'index'
657
657
658 get :index, :format => 'pdf'
658 get :index, :format => 'pdf'
659 assert_response :success
659 assert_response :success
660 assert_not_nil assigns(:issues)
660 assert_not_nil assigns(:issues)
661 assert_equal 'application/pdf', @response.content_type
661 assert_equal 'application/pdf', @response.content_type
662
662
663 get :index, :project_id => 1, :format => 'pdf'
663 get :index, :project_id => 1, :format => 'pdf'
664 assert_response :success
664 assert_response :success
665 assert_not_nil assigns(:issues)
665 assert_not_nil assigns(:issues)
666 assert_equal 'application/pdf', @response.content_type
666 assert_equal 'application/pdf', @response.content_type
667
667
668 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
668 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
669 assert_response :success
669 assert_response :success
670 assert_not_nil assigns(:issues)
670 assert_not_nil assigns(:issues)
671 assert_equal 'application/pdf', @response.content_type
671 assert_equal 'application/pdf', @response.content_type
672 end
672 end
673 end
673 end
674 end
674 end
675
675
676 def test_index_pdf_with_query_grouped_by_list_custom_field
676 def test_index_pdf_with_query_grouped_by_list_custom_field
677 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
677 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
678 assert_response :success
678 assert_response :success
679 assert_not_nil assigns(:issues)
679 assert_not_nil assigns(:issues)
680 assert_not_nil assigns(:issue_count_by_group)
680 assert_not_nil assigns(:issue_count_by_group)
681 assert_equal 'application/pdf', @response.content_type
681 assert_equal 'application/pdf', @response.content_type
682 end
682 end
683
683
684 def test_index_atom
684 def test_index_atom
685 get :index, :project_id => 'ecookbook', :format => 'atom'
685 get :index, :project_id => 'ecookbook', :format => 'atom'
686 assert_response :success
686 assert_response :success
687 assert_template 'common/feed'
687 assert_template 'common/feed'
688 assert_equal 'application/atom+xml', response.content_type
688 assert_equal 'application/atom+xml', response.content_type
689
689
690 assert_select 'feed' do
690 assert_select 'feed' do
691 assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
691 assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
692 assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
692 assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
693 assert_select 'entry link[href=?]', 'http://test.host/issues/1'
693 assert_select 'entry link[href=?]', 'http://test.host/issues/1'
694 end
694 end
695 end
695 end
696
696
697 def test_index_sort
697 def test_index_sort
698 get :index, :sort => 'tracker,id:desc'
698 get :index, :sort => 'tracker,id:desc'
699 assert_response :success
699 assert_response :success
700
700
701 sort_params = @request.session['issues_index_sort']
701 sort_params = @request.session['issues_index_sort']
702 assert sort_params.is_a?(String)
702 assert sort_params.is_a?(String)
703 assert_equal 'tracker,id:desc', sort_params
703 assert_equal 'tracker,id:desc', sort_params
704
704
705 issues = assigns(:issues)
705 issues = assigns(:issues)
706 assert_not_nil issues
706 assert_not_nil issues
707 assert !issues.empty?
707 assert !issues.empty?
708 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
708 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
709 assert_select 'table.issues.sort-by-tracker.sort-asc'
709 assert_select 'table.issues.sort-by-tracker.sort-asc'
710 end
710 end
711
711
712 def test_index_sort_by_field_not_included_in_columns
712 def test_index_sort_by_field_not_included_in_columns
713 Setting.issue_list_default_columns = %w(subject author)
713 Setting.issue_list_default_columns = %w(subject author)
714 get :index, :sort => 'tracker'
714 get :index, :sort => 'tracker'
715 end
715 end
716
716
717 def test_index_sort_by_assigned_to
717 def test_index_sort_by_assigned_to
718 get :index, :sort => 'assigned_to'
718 get :index, :sort => 'assigned_to'
719 assert_response :success
719 assert_response :success
720 assignees = assigns(:issues).collect(&:assigned_to).compact
720 assignees = assigns(:issues).collect(&:assigned_to).compact
721 assert_equal assignees.sort, assignees
721 assert_equal assignees.sort, assignees
722 assert_select 'table.issues.sort-by-assigned-to.sort-asc'
722 assert_select 'table.issues.sort-by-assigned-to.sort-asc'
723 end
723 end
724
724
725 def test_index_sort_by_assigned_to_desc
725 def test_index_sort_by_assigned_to_desc
726 get :index, :sort => 'assigned_to:desc'
726 get :index, :sort => 'assigned_to:desc'
727 assert_response :success
727 assert_response :success
728 assignees = assigns(:issues).collect(&:assigned_to).compact
728 assignees = assigns(:issues).collect(&:assigned_to).compact
729 assert_equal assignees.sort.reverse, assignees
729 assert_equal assignees.sort.reverse, assignees
730 assert_select 'table.issues.sort-by-assigned-to.sort-desc'
730 assert_select 'table.issues.sort-by-assigned-to.sort-desc'
731 end
731 end
732
732
733 def test_index_group_by_assigned_to
733 def test_index_group_by_assigned_to
734 get :index, :group_by => 'assigned_to', :sort => 'priority'
734 get :index, :group_by => 'assigned_to', :sort => 'priority'
735 assert_response :success
735 assert_response :success
736 end
736 end
737
737
738 def test_index_sort_by_author
738 def test_index_sort_by_author
739 get :index, :sort => 'author'
739 get :index, :sort => 'author'
740 assert_response :success
740 assert_response :success
741 authors = assigns(:issues).collect(&:author)
741 authors = assigns(:issues).collect(&:author)
742 assert_equal authors.sort, authors
742 assert_equal authors.sort, authors
743 end
743 end
744
744
745 def test_index_sort_by_author_desc
745 def test_index_sort_by_author_desc
746 get :index, :sort => 'author:desc'
746 get :index, :sort => 'author:desc'
747 assert_response :success
747 assert_response :success
748 authors = assigns(:issues).collect(&:author)
748 authors = assigns(:issues).collect(&:author)
749 assert_equal authors.sort.reverse, authors
749 assert_equal authors.sort.reverse, authors
750 end
750 end
751
751
752 def test_index_group_by_author
752 def test_index_group_by_author
753 get :index, :group_by => 'author', :sort => 'priority'
753 get :index, :group_by => 'author', :sort => 'priority'
754 assert_response :success
754 assert_response :success
755 end
755 end
756
756
757 def test_index_sort_by_spent_hours
757 def test_index_sort_by_spent_hours
758 get :index, :sort => 'spent_hours:desc'
758 get :index, :sort => 'spent_hours:desc'
759 assert_response :success
759 assert_response :success
760 hours = assigns(:issues).collect(&:spent_hours)
760 hours = assigns(:issues).collect(&:spent_hours)
761 assert_equal hours.sort.reverse, hours
761 assert_equal hours.sort.reverse, hours
762 end
762 end
763
763
764 def test_index_sort_by_total_spent_hours
764 def test_index_sort_by_total_spent_hours
765 get :index, :sort => 'total_spent_hours:desc'
765 get :index, :sort => 'total_spent_hours:desc'
766 assert_response :success
766 assert_response :success
767 hours = assigns(:issues).collect(&:total_spent_hours)
767 hours = assigns(:issues).collect(&:total_spent_hours)
768 assert_equal hours.sort.reverse, hours
768 assert_equal hours.sort.reverse, hours
769 end
769 end
770
770
771 def test_index_sort_by_total_estimated_hours
771 def test_index_sort_by_total_estimated_hours
772 get :index, :sort => 'total_estimated_hours:desc'
772 get :index, :sort => 'total_estimated_hours:desc'
773 assert_response :success
773 assert_response :success
774 hours = assigns(:issues).collect(&:total_estimated_hours)
774 hours = assigns(:issues).collect(&:total_estimated_hours)
775 assert_equal hours.sort.reverse, hours
775 assert_equal hours.sort.reverse, hours
776 end
776 end
777
777
778 def test_index_sort_by_user_custom_field
778 def test_index_sort_by_user_custom_field
779 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
779 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
780 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
780 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
781 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
781 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
782 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
782 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
783 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
783 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
784
784
785 get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
785 get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
786 assert_response :success
786 assert_response :success
787
787
788 assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
788 assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
789 end
789 end
790
790
791 def test_index_with_columns
791 def test_index_with_columns
792 columns = ['tracker', 'subject', 'assigned_to']
792 columns = ['tracker', 'subject', 'assigned_to']
793 get :index, :set_filter => 1, :c => columns
793 get :index, :set_filter => 1, :c => columns
794 assert_response :success
794 assert_response :success
795
795
796 # query should use specified columns
796 # query should use specified columns
797 query = assigns(:query)
797 query = assigns(:query)
798 assert_kind_of IssueQuery, query
798 assert_kind_of IssueQuery, query
799 assert_equal columns, query.column_names.map(&:to_s)
799 assert_equal columns, query.column_names.map(&:to_s)
800
800
801 # columns should be stored in session
801 # columns should be stored in session
802 assert_kind_of Hash, session[:query]
802 assert_kind_of Hash, session[:query]
803 assert_kind_of Array, session[:query][:column_names]
803 assert_kind_of Array, session[:query][:column_names]
804 assert_equal columns, session[:query][:column_names].map(&:to_s)
804 assert_equal columns, session[:query][:column_names].map(&:to_s)
805
805
806 # ensure only these columns are kept in the selected columns list
806 # ensure only these columns are kept in the selected columns list
807 assert_select 'select#selected_columns option' do
807 assert_select 'select#selected_columns option' do
808 assert_select 'option', 3
808 assert_select 'option', 3
809 assert_select 'option[value=tracker]'
809 assert_select 'option[value=tracker]'
810 assert_select 'option[value=project]', 0
810 assert_select 'option[value=project]', 0
811 end
811 end
812 end
812 end
813
813
814 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
814 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
815 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
815 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
816 get :index, :set_filter => 1
816 get :index, :set_filter => 1
817
817
818 # query should use specified columns
818 # query should use specified columns
819 query = assigns(:query)
819 query = assigns(:query)
820 assert_kind_of IssueQuery, query
820 assert_kind_of IssueQuery, query
821 assert_equal [:id, :project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
821 assert_equal [:id, :project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
822 end
822 end
823
823
824 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
824 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
825 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
825 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
826 columns = ['id', 'tracker', 'subject', 'assigned_to']
826 columns = ['id', 'tracker', 'subject', 'assigned_to']
827 get :index, :set_filter => 1, :c => columns
827 get :index, :set_filter => 1, :c => columns
828
828
829 # query should use specified columns
829 # query should use specified columns
830 query = assigns(:query)
830 query = assigns(:query)
831 assert_kind_of IssueQuery, query
831 assert_kind_of IssueQuery, query
832 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
832 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
833 end
833 end
834
834
835 def test_index_with_default_columns_should_respect_default_columns_order
835 def test_index_with_default_columns_should_respect_default_columns_order
836 columns = ['assigned_to', 'subject', 'status', 'tracker']
836 columns = ['assigned_to', 'subject', 'status', 'tracker']
837 with_settings :issue_list_default_columns => columns do
837 with_settings :issue_list_default_columns => columns do
838 get :index, :project_id => 1, :set_filter => 1
838 get :index, :project_id => 1, :set_filter => 1
839
839
840 query = assigns(:query)
840 query = assigns(:query)
841 assert_equal (['id'] + columns).map(&:to_sym), query.columns.map(&:name)
841 assert_equal (['id'] + columns).map(&:to_sym), query.columns.map(&:name)
842 end
842 end
843 end
843 end
844
844
845 def test_index_with_custom_field_column
845 def test_index_with_custom_field_column
846 columns = %w(tracker subject cf_2)
846 columns = %w(tracker subject cf_2)
847 get :index, :set_filter => 1, :c => columns
847 get :index, :set_filter => 1, :c => columns
848 assert_response :success
848 assert_response :success
849
849
850 # query should use specified columns
850 # query should use specified columns
851 query = assigns(:query)
851 query = assigns(:query)
852 assert_kind_of IssueQuery, query
852 assert_kind_of IssueQuery, query
853 assert_equal columns, query.column_names.map(&:to_s)
853 assert_equal columns, query.column_names.map(&:to_s)
854
854
855 assert_select 'table.issues td.cf_2.string'
855 assert_select 'table.issues td.cf_2.string'
856 end
856 end
857
857
858 def test_index_with_multi_custom_field_column
858 def test_index_with_multi_custom_field_column
859 field = CustomField.find(1)
859 field = CustomField.find(1)
860 field.update_attribute :multiple, true
860 field.update_attribute :multiple, true
861 issue = Issue.find(1)
861 issue = Issue.find(1)
862 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
862 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
863 issue.save!
863 issue.save!
864
864
865 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
865 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
866 assert_response :success
866 assert_response :success
867
867
868 assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
868 assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
869 end
869 end
870
870
871 def test_index_with_multi_user_custom_field_column
871 def test_index_with_multi_user_custom_field_column
872 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
872 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
873 :tracker_ids => [1], :is_for_all => true)
873 :tracker_ids => [1], :is_for_all => true)
874 issue = Issue.find(1)
874 issue = Issue.find(1)
875 issue.custom_field_values = {field.id => ['2', '3']}
875 issue.custom_field_values = {field.id => ['2', '3']}
876 issue.save!
876 issue.save!
877
877
878 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
878 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
879 assert_response :success
879 assert_response :success
880
880
881 assert_select "table.issues td.cf_#{field.id}" do
881 assert_select "table.issues td.cf_#{field.id}" do
882 assert_select 'a', 2
882 assert_select 'a', 2
883 assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
883 assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
884 assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
884 assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
885 end
885 end
886 end
886 end
887
887
888 def test_index_with_date_column
888 def test_index_with_date_column
889 with_settings :date_format => '%d/%m/%Y' do
889 with_settings :date_format => '%d/%m/%Y' do
890 Issue.find(1).update_attribute :start_date, '1987-08-24'
890 Issue.find(1).update_attribute :start_date, '1987-08-24'
891 get :index, :set_filter => 1, :c => %w(start_date)
891 get :index, :set_filter => 1, :c => %w(start_date)
892 assert_select "table.issues td.start_date", :text => '24/08/1987'
892 assert_select "table.issues td.start_date", :text => '24/08/1987'
893 end
893 end
894 end
894 end
895
895
896 def test_index_with_done_ratio_column
896 def test_index_with_done_ratio_column
897 Issue.find(1).update_attribute :done_ratio, 40
897 Issue.find(1).update_attribute :done_ratio, 40
898 get :index, :set_filter => 1, :c => %w(done_ratio)
898 get :index, :set_filter => 1, :c => %w(done_ratio)
899 assert_select 'table.issues td.done_ratio' do
899 assert_select 'table.issues td.done_ratio' do
900 assert_select 'table.progress' do
900 assert_select 'table.progress' do
901 assert_select 'td.closed[style=?]', 'width: 40%;'
901 assert_select 'td.closed[style=?]', 'width: 40%;'
902 end
902 end
903 end
903 end
904 end
904 end
905
905
906 def test_index_with_spent_hours_column
906 def test_index_with_spent_hours_column
907 Issue.expects(:load_visible_spent_hours).once
907 Issue.expects(:load_visible_spent_hours).once
908 get :index, :set_filter => 1, :c => %w(subject spent_hours)
908 get :index, :set_filter => 1, :c => %w(subject spent_hours)
909 assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
909 assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
910 end
910 end
911
911
912 def test_index_with_total_spent_hours_column
912 def test_index_with_total_spent_hours_column
913 Issue.expects(:load_visible_total_spent_hours).once
913 Issue.expects(:load_visible_total_spent_hours).once
914 get :index, :set_filter => 1, :c => %w(subject total_spent_hours)
914 get :index, :set_filter => 1, :c => %w(subject total_spent_hours)
915 assert_select 'table.issues tr#issue-3 td.total_spent_hours', :text => '1.00'
915 assert_select 'table.issues tr#issue-3 td.total_spent_hours', :text => '1.00'
916 end
916 end
917
917
918 def test_index_with_total_estimated_hours_column
918 def test_index_with_total_estimated_hours_column
919 get :index, :set_filter => 1, :c => %w(subject total_estimated_hours)
919 get :index, :set_filter => 1, :c => %w(subject total_estimated_hours)
920 assert_select 'table.issues td.total_estimated_hours'
920 assert_select 'table.issues td.total_estimated_hours'
921 end
921 end
922
922
923 def test_index_should_not_show_spent_hours_column_without_permission
923 def test_index_should_not_show_spent_hours_column_without_permission
924 Role.anonymous.remove_permission! :view_time_entries
924 Role.anonymous.remove_permission! :view_time_entries
925 get :index, :set_filter => 1, :c => %w(subject spent_hours)
925 get :index, :set_filter => 1, :c => %w(subject spent_hours)
926 assert_select 'td.spent_hours', 0
926 assert_select 'td.spent_hours', 0
927 end
927 end
928
928
929 def test_index_with_fixed_version_column
929 def test_index_with_fixed_version_column
930 get :index, :set_filter => 1, :c => %w(fixed_version)
930 get :index, :set_filter => 1, :c => %w(fixed_version)
931 assert_select 'table.issues td.fixed_version' do
931 assert_select 'table.issues td.fixed_version' do
932 assert_select 'a[href=?]', '/versions/2', :text => 'eCookbook - 1.0'
932 assert_select 'a[href=?]', '/versions/2', :text => 'eCookbook - 1.0'
933 end
933 end
934 end
934 end
935
935
936 def test_index_with_relations_column
936 def test_index_with_relations_column
937 IssueRelation.delete_all
937 IssueRelation.delete_all
938 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
938 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
939 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
939 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
940 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
940 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
941 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
941 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
942
942
943 get :index, :set_filter => 1, :c => %w(subject relations)
943 get :index, :set_filter => 1, :c => %w(subject relations)
944 assert_response :success
944 assert_response :success
945 assert_select "tr#issue-1 td.relations" do
945 assert_select "tr#issue-1 td.relations" do
946 assert_select "span", 3
946 assert_select "span", 3
947 assert_select "span", :text => "Related to #7"
947 assert_select "span", :text => "Related to #7"
948 assert_select "span", :text => "Related to #8"
948 assert_select "span", :text => "Related to #8"
949 assert_select "span", :text => "Blocks #11"
949 assert_select "span", :text => "Blocks #11"
950 end
950 end
951 assert_select "tr#issue-2 td.relations" do
951 assert_select "tr#issue-2 td.relations" do
952 assert_select "span", 1
952 assert_select "span", 1
953 assert_select "span", :text => "Blocked by #12"
953 assert_select "span", :text => "Blocked by #12"
954 end
954 end
955 assert_select "tr#issue-3 td.relations" do
955 assert_select "tr#issue-3 td.relations" do
956 assert_select "span", 0
956 assert_select "span", 0
957 end
957 end
958
958
959 get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
959 get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
960 assert_response :success
960 assert_response :success
961 assert_equal 'text/csv; header=present', response.content_type
961 assert_equal 'text/csv; header=present', response.content_type
962 lines = response.body.chomp.split("\n")
962 lines = response.body.chomp.split("\n")
963 assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
963 assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
964 assert_include '2,Blocked by #12', lines
964 assert_include '2,Blocked by #12', lines
965 assert_include '3,""', lines
965 assert_include '3,""', lines
966
966
967 get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
967 get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
968 assert_response :success
968 assert_response :success
969 assert_equal 'application/pdf', response.content_type
969 assert_equal 'application/pdf', response.content_type
970 end
970 end
971
971
972 def test_index_with_description_column
972 def test_index_with_description_column
973 get :index, :set_filter => 1, :c => %w(subject description)
973 get :index, :set_filter => 1, :c => %w(subject description)
974
974
975 assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
975 assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
976 assert_select 'td.description[colspan="3"]', :text => 'Unable to print recipes'
976 assert_select 'td.description[colspan="3"]', :text => 'Unable to print recipes'
977
977
978 get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
978 get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
979 assert_response :success
979 assert_response :success
980 assert_equal 'application/pdf', response.content_type
980 assert_equal 'application/pdf', response.content_type
981 end
981 end
982
982
983 def test_index_with_parent_column
983 def test_index_with_parent_column
984 Issue.delete_all
984 Issue.delete_all
985 parent = Issue.generate!
985 parent = Issue.generate!
986 child = Issue.generate!(:parent_issue_id => parent.id)
986 child = Issue.generate!(:parent_issue_id => parent.id)
987
987
988 get :index, :c => %w(parent)
988 get :index, :c => %w(parent)
989
989
990 assert_select 'td.parent', :text => "#{parent.tracker} ##{parent.id}"
990 assert_select 'td.parent', :text => "#{parent.tracker} ##{parent.id}"
991 assert_select 'td.parent a[title=?]', parent.subject
991 assert_select 'td.parent a[title=?]', parent.subject
992 end
992 end
993
993
994 def test_index_with_estimated_hours_total
994 def test_index_with_estimated_hours_total
995 Issue.delete_all
995 Issue.delete_all
996 Issue.generate!(:estimated_hours => 5.5)
996 Issue.generate!(:estimated_hours => 5.5)
997 Issue.generate!(:estimated_hours => 1.1)
997 Issue.generate!(:estimated_hours => 1.1)
998
998
999 get :index, :t => %w(estimated_hours)
999 get :index, :t => %w(estimated_hours)
1000 assert_response :success
1000 assert_response :success
1001 assert_select '.query-totals'
1001 assert_select '.query-totals'
1002 assert_select '.total-for-estimated-hours span.value', :text => '6.60'
1002 assert_select '.total-for-estimated-hours span.value', :text => '6.60'
1003 assert_select 'input[type=checkbox][name=?][value=estimated_hours][checked=checked]', 't[]'
1003 assert_select 'input[type=checkbox][name=?][value=estimated_hours][checked=checked]', 't[]'
1004 end
1004 end
1005
1005
1006 def test_index_with_grouped_query_and_estimated_hours_total
1006 def test_index_with_grouped_query_and_estimated_hours_total
1007 Issue.delete_all
1007 Issue.delete_all
1008 Issue.generate!(:estimated_hours => 5.5, :category_id => 1)
1008 Issue.generate!(:estimated_hours => 5.5, :category_id => 1)
1009 Issue.generate!(:estimated_hours => 2.3, :category_id => 1)
1009 Issue.generate!(:estimated_hours => 2.3, :category_id => 1)
1010 Issue.generate!(:estimated_hours => 1.1, :category_id => 2)
1010 Issue.generate!(:estimated_hours => 1.1, :category_id => 2)
1011 Issue.generate!(:estimated_hours => 4.6)
1011 Issue.generate!(:estimated_hours => 4.6)
1012
1012
1013 get :index, :t => %w(estimated_hours), :group_by => 'category'
1013 get :index, :t => %w(estimated_hours), :group_by => 'category'
1014 assert_response :success
1014 assert_response :success
1015 assert_select '.query-totals'
1015 assert_select '.query-totals'
1016 assert_select '.query-totals .total-for-estimated-hours span.value', :text => '13.50'
1016 assert_select '.query-totals .total-for-estimated-hours span.value', :text => '13.50'
1017 assert_select 'tr.group', :text => /Printing/ do
1017 assert_select 'tr.group', :text => /Printing/ do
1018 assert_select '.total-for-estimated-hours span.value', :text => '7.80'
1018 assert_select '.total-for-estimated-hours span.value', :text => '7.80'
1019 end
1019 end
1020 assert_select 'tr.group', :text => /Recipes/ do
1020 assert_select 'tr.group', :text => /Recipes/ do
1021 assert_select '.total-for-estimated-hours span.value', :text => '1.10'
1021 assert_select '.total-for-estimated-hours span.value', :text => '1.10'
1022 end
1022 end
1023 assert_select 'tr.group', :text => /blank/ do
1023 assert_select 'tr.group', :text => /blank/ do
1024 assert_select '.total-for-estimated-hours span.value', :text => '4.60'
1024 assert_select '.total-for-estimated-hours span.value', :text => '4.60'
1025 end
1025 end
1026 end
1026 end
1027
1027
1028 def test_index_with_int_custom_field_total
1028 def test_index_with_int_custom_field_total
1029 field = IssueCustomField.generate!(:field_format => 'int', :is_for_all => true)
1029 field = IssueCustomField.generate!(:field_format => 'int', :is_for_all => true)
1030 CustomValue.create!(:customized => Issue.find(1), :custom_field => field, :value => '2')
1030 CustomValue.create!(:customized => Issue.find(1), :custom_field => field, :value => '2')
1031 CustomValue.create!(:customized => Issue.find(2), :custom_field => field, :value => '7')
1031 CustomValue.create!(:customized => Issue.find(2), :custom_field => field, :value => '7')
1032
1032
1033 get :index, :t => ["cf_#{field.id}"]
1033 get :index, :t => ["cf_#{field.id}"]
1034 assert_response :success
1034 assert_response :success
1035 assert_select '.query-totals'
1035 assert_select '.query-totals'
1036 assert_select ".total-for-cf-#{field.id} span.value", :text => '9'
1036 assert_select ".total-for-cf-#{field.id} span.value", :text => '9'
1037 end
1037 end
1038
1038
1039 def test_index_totals_should_default_to_settings
1039 def test_index_totals_should_default_to_settings
1040 with_settings :issue_list_default_totals => ['estimated_hours'] do
1040 with_settings :issue_list_default_totals => ['estimated_hours'] do
1041 get :index
1041 get :index
1042 assert_response :success
1042 assert_response :success
1043 assert_select '.total-for-estimated-hours span.value'
1043 assert_select '.total-for-estimated-hours span.value'
1044 assert_select '.query-totals>span', 1
1044 assert_select '.query-totals>span', 1
1045 end
1045 end
1046 end
1046 end
1047
1047
1048 def test_index_send_html_if_query_is_invalid
1048 def test_index_send_html_if_query_is_invalid
1049 get :index, :f => ['start_date'], :op => {:start_date => '='}
1049 get :index, :f => ['start_date'], :op => {:start_date => '='}
1050 assert_equal 'text/html', @response.content_type
1050 assert_equal 'text/html', @response.content_type
1051 assert_template 'index'
1051 assert_template 'index'
1052 end
1052 end
1053
1053
1054 def test_index_send_nothing_if_query_is_invalid
1054 def test_index_send_nothing_if_query_is_invalid
1055 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
1055 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
1056 assert_equal 'text/csv', @response.content_type
1056 assert_equal 'text/csv', @response.content_type
1057 assert @response.body.blank?
1057 assert @response.body.blank?
1058 end
1058 end
1059
1059
1060 def test_index_should_include_new_issue_link
1060 def test_index_should_include_new_issue_link
1061 @request.session[:user_id] = 2
1061 @request.session[:user_id] = 2
1062 get :index, :project_id => 1
1062 get :index, :project_id => 1
1063 assert_select 'a.new-issue[href="/projects/ecookbook/issues/new"]', :text => 'New issue'
1063 assert_select 'a.new-issue[href="/projects/ecookbook/issues/new"]', :text => 'New issue'
1064 end
1064 end
1065
1065
1066 def test_index_should_not_include_new_issue_link_for_project_without_trackers
1066 def test_index_should_not_include_new_issue_link_for_project_without_trackers
1067 Project.find(1).trackers.clear
1067 Project.find(1).trackers.clear
1068
1068
1069 @request.session[:user_id] = 2
1069 @request.session[:user_id] = 2
1070 get :index, :project_id => 1
1070 get :index, :project_id => 1
1071 assert_select 'a.new-issue', 0
1071 assert_select 'a.new-issue', 0
1072 end
1072 end
1073
1073
1074 def test_index_should_not_include_new_issue_link_for_users_with_copy_issues_permission_only
1074 def test_index_should_not_include_new_issue_link_for_users_with_copy_issues_permission_only
1075 role = Role.find(1)
1075 role = Role.find(1)
1076 role.remove_permission! :add_issues
1076 role.remove_permission! :add_issues
1077 role.add_permission! :copy_issues
1077 role.add_permission! :copy_issues
1078
1078
1079 @request.session[:user_id] = 2
1079 @request.session[:user_id] = 2
1080 get :index, :project_id => 1
1080 get :index, :project_id => 1
1081 assert_select 'a.new-issue', 0
1081 assert_select 'a.new-issue', 0
1082 end
1082 end
1083
1083
1084 def test_index_without_project_should_include_new_issue_link
1085 @request.session[:user_id] = 2
1086 get :index
1087 assert_select 'a.new-issue[href="/issues/new"]', :text => 'New issue'
1088 end
1089
1084 def test_show_by_anonymous
1090 def test_show_by_anonymous
1085 get :show, :id => 1
1091 get :show, :id => 1
1086 assert_response :success
1092 assert_response :success
1087 assert_template 'show'
1093 assert_template 'show'
1088 assert_equal Issue.find(1), assigns(:issue)
1094 assert_equal Issue.find(1), assigns(:issue)
1089 assert_select 'div.issue div.description', :text => /Unable to print recipes/
1095 assert_select 'div.issue div.description', :text => /Unable to print recipes/
1090 # anonymous role is allowed to add a note
1096 # anonymous role is allowed to add a note
1091 assert_select 'form#issue-form' do
1097 assert_select 'form#issue-form' do
1092 assert_select 'fieldset' do
1098 assert_select 'fieldset' do
1093 assert_select 'legend', :text => 'Notes'
1099 assert_select 'legend', :text => 'Notes'
1094 assert_select 'textarea[name=?]', 'issue[notes]'
1100 assert_select 'textarea[name=?]', 'issue[notes]'
1095 end
1101 end
1096 end
1102 end
1097 assert_select 'title', :text => "Bug #1: Cannot print recipes - eCookbook - Redmine"
1103 assert_select 'title', :text => "Bug #1: Cannot print recipes - eCookbook - Redmine"
1098 end
1104 end
1099
1105
1100 def test_show_by_manager
1106 def test_show_by_manager
1101 @request.session[:user_id] = 2
1107 @request.session[:user_id] = 2
1102 get :show, :id => 1
1108 get :show, :id => 1
1103 assert_response :success
1109 assert_response :success
1104 assert_select 'a', :text => /Quote/
1110 assert_select 'a', :text => /Quote/
1105 assert_select 'form#issue-form' do
1111 assert_select 'form#issue-form' do
1106 assert_select 'fieldset' do
1112 assert_select 'fieldset' do
1107 assert_select 'legend', :text => 'Change properties'
1113 assert_select 'legend', :text => 'Change properties'
1108 assert_select 'input[name=?]', 'issue[subject]'
1114 assert_select 'input[name=?]', 'issue[subject]'
1109 end
1115 end
1110 assert_select 'fieldset' do
1116 assert_select 'fieldset' do
1111 assert_select 'legend', :text => 'Log time'
1117 assert_select 'legend', :text => 'Log time'
1112 assert_select 'input[name=?]', 'time_entry[hours]'
1118 assert_select 'input[name=?]', 'time_entry[hours]'
1113 end
1119 end
1114 assert_select 'fieldset' do
1120 assert_select 'fieldset' do
1115 assert_select 'legend', :text => 'Notes'
1121 assert_select 'legend', :text => 'Notes'
1116 assert_select 'textarea[name=?]', 'issue[notes]'
1122 assert_select 'textarea[name=?]', 'issue[notes]'
1117 end
1123 end
1118 end
1124 end
1119 end
1125 end
1120
1126
1121 def test_show_should_display_update_form
1127 def test_show_should_display_update_form
1122 @request.session[:user_id] = 2
1128 @request.session[:user_id] = 2
1123 get :show, :id => 1
1129 get :show, :id => 1
1124 assert_response :success
1130 assert_response :success
1125
1131
1126 assert_select 'form#issue-form' do
1132 assert_select 'form#issue-form' do
1127 assert_select 'input[name=?]', 'issue[is_private]'
1133 assert_select 'input[name=?]', 'issue[is_private]'
1128 assert_select 'select[name=?]', 'issue[project_id]'
1134 assert_select 'select[name=?]', 'issue[project_id]'
1129 assert_select 'select[name=?]', 'issue[tracker_id]'
1135 assert_select 'select[name=?]', 'issue[tracker_id]'
1130 assert_select 'input[name=?]', 'issue[subject]'
1136 assert_select 'input[name=?]', 'issue[subject]'
1131 assert_select 'textarea[name=?]', 'issue[description]'
1137 assert_select 'textarea[name=?]', 'issue[description]'
1132 assert_select 'select[name=?]', 'issue[status_id]'
1138 assert_select 'select[name=?]', 'issue[status_id]'
1133 assert_select 'select[name=?]', 'issue[priority_id]'
1139 assert_select 'select[name=?]', 'issue[priority_id]'
1134 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1140 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1135 assert_select 'select[name=?]', 'issue[category_id]'
1141 assert_select 'select[name=?]', 'issue[category_id]'
1136 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1142 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1137 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1143 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1138 assert_select 'input[name=?]', 'issue[start_date]'
1144 assert_select 'input[name=?]', 'issue[start_date]'
1139 assert_select 'input[name=?]', 'issue[due_date]'
1145 assert_select 'input[name=?]', 'issue[due_date]'
1140 assert_select 'select[name=?]', 'issue[done_ratio]'
1146 assert_select 'select[name=?]', 'issue[done_ratio]'
1141 assert_select 'input[name=?]', 'issue[custom_field_values][2]'
1147 assert_select 'input[name=?]', 'issue[custom_field_values][2]'
1142 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1148 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1143 assert_select 'textarea[name=?]', 'issue[notes]'
1149 assert_select 'textarea[name=?]', 'issue[notes]'
1144 end
1150 end
1145 end
1151 end
1146
1152
1147 def test_show_should_display_update_form_with_minimal_permissions
1153 def test_show_should_display_update_form_with_minimal_permissions
1148 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
1154 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
1149 WorkflowTransition.delete_all :role_id => 1
1155 WorkflowTransition.delete_all :role_id => 1
1150
1156
1151 @request.session[:user_id] = 2
1157 @request.session[:user_id] = 2
1152 get :show, :id => 1
1158 get :show, :id => 1
1153 assert_response :success
1159 assert_response :success
1154
1160
1155 assert_select 'form#issue-form' do
1161 assert_select 'form#issue-form' do
1156 assert_select 'input[name=?]', 'issue[is_private]', 0
1162 assert_select 'input[name=?]', 'issue[is_private]', 0
1157 assert_select 'select[name=?]', 'issue[project_id]', 0
1163 assert_select 'select[name=?]', 'issue[project_id]', 0
1158 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1164 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1159 assert_select 'input[name=?]', 'issue[subject]', 0
1165 assert_select 'input[name=?]', 'issue[subject]', 0
1160 assert_select 'textarea[name=?]', 'issue[description]', 0
1166 assert_select 'textarea[name=?]', 'issue[description]', 0
1161 assert_select 'select[name=?]', 'issue[status_id]', 0
1167 assert_select 'select[name=?]', 'issue[status_id]', 0
1162 assert_select 'select[name=?]', 'issue[priority_id]', 0
1168 assert_select 'select[name=?]', 'issue[priority_id]', 0
1163 assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
1169 assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
1164 assert_select 'select[name=?]', 'issue[category_id]', 0
1170 assert_select 'select[name=?]', 'issue[category_id]', 0
1165 assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
1171 assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
1166 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1172 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1167 assert_select 'input[name=?]', 'issue[start_date]', 0
1173 assert_select 'input[name=?]', 'issue[start_date]', 0
1168 assert_select 'input[name=?]', 'issue[due_date]', 0
1174 assert_select 'input[name=?]', 'issue[due_date]', 0
1169 assert_select 'select[name=?]', 'issue[done_ratio]', 0
1175 assert_select 'select[name=?]', 'issue[done_ratio]', 0
1170 assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
1176 assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
1171 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1177 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1172 assert_select 'textarea[name=?]', 'issue[notes]'
1178 assert_select 'textarea[name=?]', 'issue[notes]'
1173 end
1179 end
1174 end
1180 end
1175
1181
1176 def test_show_should_not_display_update_form_without_permissions
1182 def test_show_should_not_display_update_form_without_permissions
1177 Role.find(1).update_attribute :permissions, [:view_issues]
1183 Role.find(1).update_attribute :permissions, [:view_issues]
1178
1184
1179 @request.session[:user_id] = 2
1185 @request.session[:user_id] = 2
1180 get :show, :id => 1
1186 get :show, :id => 1
1181 assert_response :success
1187 assert_response :success
1182
1188
1183 assert_select 'form#issue-form', 0
1189 assert_select 'form#issue-form', 0
1184 end
1190 end
1185
1191
1186 def test_update_form_should_not_display_inactive_enumerations
1192 def test_update_form_should_not_display_inactive_enumerations
1187 assert !IssuePriority.find(15).active?
1193 assert !IssuePriority.find(15).active?
1188
1194
1189 @request.session[:user_id] = 2
1195 @request.session[:user_id] = 2
1190 get :show, :id => 1
1196 get :show, :id => 1
1191 assert_response :success
1197 assert_response :success
1192
1198
1193 assert_select 'form#issue-form' do
1199 assert_select 'form#issue-form' do
1194 assert_select 'select[name=?]', 'issue[priority_id]' do
1200 assert_select 'select[name=?]', 'issue[priority_id]' do
1195 assert_select 'option[value="4"]'
1201 assert_select 'option[value="4"]'
1196 assert_select 'option[value="15"]', 0
1202 assert_select 'option[value="15"]', 0
1197 end
1203 end
1198 end
1204 end
1199 end
1205 end
1200
1206
1201 def test_update_form_should_allow_attachment_upload
1207 def test_update_form_should_allow_attachment_upload
1202 @request.session[:user_id] = 2
1208 @request.session[:user_id] = 2
1203 get :show, :id => 1
1209 get :show, :id => 1
1204
1210
1205 assert_select 'form#issue-form[method=post][enctype="multipart/form-data"]' do
1211 assert_select 'form#issue-form[method=post][enctype="multipart/form-data"]' do
1206 assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
1212 assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
1207 end
1213 end
1208 end
1214 end
1209
1215
1210 def test_show_should_deny_anonymous_access_without_permission
1216 def test_show_should_deny_anonymous_access_without_permission
1211 Role.anonymous.remove_permission!(:view_issues)
1217 Role.anonymous.remove_permission!(:view_issues)
1212 get :show, :id => 1
1218 get :show, :id => 1
1213 assert_response :redirect
1219 assert_response :redirect
1214 end
1220 end
1215
1221
1216 def test_show_should_deny_anonymous_access_to_private_issue
1222 def test_show_should_deny_anonymous_access_to_private_issue
1217 Issue.where(:id => 1).update_all(["is_private = ?", true])
1223 Issue.where(:id => 1).update_all(["is_private = ?", true])
1218 get :show, :id => 1
1224 get :show, :id => 1
1219 assert_response :redirect
1225 assert_response :redirect
1220 end
1226 end
1221
1227
1222 def test_show_should_deny_non_member_access_without_permission
1228 def test_show_should_deny_non_member_access_without_permission
1223 Role.non_member.remove_permission!(:view_issues)
1229 Role.non_member.remove_permission!(:view_issues)
1224 @request.session[:user_id] = 9
1230 @request.session[:user_id] = 9
1225 get :show, :id => 1
1231 get :show, :id => 1
1226 assert_response 403
1232 assert_response 403
1227 end
1233 end
1228
1234
1229 def test_show_should_deny_non_member_access_to_private_issue
1235 def test_show_should_deny_non_member_access_to_private_issue
1230 Issue.where(:id => 1).update_all(["is_private = ?", true])
1236 Issue.where(:id => 1).update_all(["is_private = ?", true])
1231 @request.session[:user_id] = 9
1237 @request.session[:user_id] = 9
1232 get :show, :id => 1
1238 get :show, :id => 1
1233 assert_response 403
1239 assert_response 403
1234 end
1240 end
1235
1241
1236 def test_show_should_deny_member_access_without_permission
1242 def test_show_should_deny_member_access_without_permission
1237 Role.find(1).remove_permission!(:view_issues)
1243 Role.find(1).remove_permission!(:view_issues)
1238 @request.session[:user_id] = 2
1244 @request.session[:user_id] = 2
1239 get :show, :id => 1
1245 get :show, :id => 1
1240 assert_response 403
1246 assert_response 403
1241 end
1247 end
1242
1248
1243 def test_show_should_deny_member_access_to_private_issue_without_permission
1249 def test_show_should_deny_member_access_to_private_issue_without_permission
1244 Issue.where(:id => 1).update_all(["is_private = ?", true])
1250 Issue.where(:id => 1).update_all(["is_private = ?", true])
1245 @request.session[:user_id] = 3
1251 @request.session[:user_id] = 3
1246 get :show, :id => 1
1252 get :show, :id => 1
1247 assert_response 403
1253 assert_response 403
1248 end
1254 end
1249
1255
1250 def test_show_should_allow_author_access_to_private_issue
1256 def test_show_should_allow_author_access_to_private_issue
1251 Issue.where(:id => 1).update_all(["is_private = ?, author_id = 3", true])
1257 Issue.where(:id => 1).update_all(["is_private = ?, author_id = 3", true])
1252 @request.session[:user_id] = 3
1258 @request.session[:user_id] = 3
1253 get :show, :id => 1
1259 get :show, :id => 1
1254 assert_response :success
1260 assert_response :success
1255 end
1261 end
1256
1262
1257 def test_show_should_allow_assignee_access_to_private_issue
1263 def test_show_should_allow_assignee_access_to_private_issue
1258 Issue.where(:id => 1).update_all(["is_private = ?, assigned_to_id = 3", true])
1264 Issue.where(:id => 1).update_all(["is_private = ?, assigned_to_id = 3", true])
1259 @request.session[:user_id] = 3
1265 @request.session[:user_id] = 3
1260 get :show, :id => 1
1266 get :show, :id => 1
1261 assert_response :success
1267 assert_response :success
1262 end
1268 end
1263
1269
1264 def test_show_should_allow_member_access_to_private_issue_with_permission
1270 def test_show_should_allow_member_access_to_private_issue_with_permission
1265 Issue.where(:id => 1).update_all(["is_private = ?", true])
1271 Issue.where(:id => 1).update_all(["is_private = ?", true])
1266 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1272 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1267 @request.session[:user_id] = 3
1273 @request.session[:user_id] = 3
1268 get :show, :id => 1
1274 get :show, :id => 1
1269 assert_response :success
1275 assert_response :success
1270 end
1276 end
1271
1277
1272 def test_show_should_not_disclose_relations_to_invisible_issues
1278 def test_show_should_not_disclose_relations_to_invisible_issues
1273 Setting.cross_project_issue_relations = '1'
1279 Setting.cross_project_issue_relations = '1'
1274 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1280 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1275 # Relation to a private project issue
1281 # Relation to a private project issue
1276 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1282 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1277
1283
1278 get :show, :id => 1
1284 get :show, :id => 1
1279 assert_response :success
1285 assert_response :success
1280
1286
1281 assert_select 'div#relations' do
1287 assert_select 'div#relations' do
1282 assert_select 'a', :text => /#2$/
1288 assert_select 'a', :text => /#2$/
1283 assert_select 'a', :text => /#4$/, :count => 0
1289 assert_select 'a', :text => /#4$/, :count => 0
1284 end
1290 end
1285 end
1291 end
1286
1292
1287 def test_show_should_list_subtasks
1293 def test_show_should_list_subtasks
1288 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1294 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1289
1295
1290 get :show, :id => 1
1296 get :show, :id => 1
1291 assert_response :success
1297 assert_response :success
1292
1298
1293 assert_select 'div#issue_tree' do
1299 assert_select 'div#issue_tree' do
1294 assert_select 'td.subject', :text => /Child Issue/
1300 assert_select 'td.subject', :text => /Child Issue/
1295 end
1301 end
1296 end
1302 end
1297
1303
1298 def test_show_should_list_parents
1304 def test_show_should_list_parents
1299 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1305 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1300
1306
1301 get :show, :id => issue.id
1307 get :show, :id => issue.id
1302 assert_response :success
1308 assert_response :success
1303
1309
1304 assert_select 'div.subject' do
1310 assert_select 'div.subject' do
1305 assert_select 'h3', 'Child Issue'
1311 assert_select 'h3', 'Child Issue'
1306 assert_select 'a[href="/issues/1"]'
1312 assert_select 'a[href="/issues/1"]'
1307 end
1313 end
1308 end
1314 end
1309
1315
1310 def test_show_should_not_display_prev_next_links_without_query_in_session
1316 def test_show_should_not_display_prev_next_links_without_query_in_session
1311 get :show, :id => 1
1317 get :show, :id => 1
1312 assert_response :success
1318 assert_response :success
1313 assert_nil assigns(:prev_issue_id)
1319 assert_nil assigns(:prev_issue_id)
1314 assert_nil assigns(:next_issue_id)
1320 assert_nil assigns(:next_issue_id)
1315
1321
1316 assert_select 'div.next-prev-links', 0
1322 assert_select 'div.next-prev-links', 0
1317 end
1323 end
1318
1324
1319 def test_show_should_display_prev_next_links_with_query_in_session
1325 def test_show_should_display_prev_next_links_with_query_in_session
1320 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1326 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1321 @request.session['issues_index_sort'] = 'id'
1327 @request.session['issues_index_sort'] = 'id'
1322
1328
1323 with_settings :display_subprojects_issues => '0' do
1329 with_settings :display_subprojects_issues => '0' do
1324 get :show, :id => 3
1330 get :show, :id => 3
1325 end
1331 end
1326
1332
1327 assert_response :success
1333 assert_response :success
1328 # Previous and next issues for all projects
1334 # Previous and next issues for all projects
1329 assert_equal 2, assigns(:prev_issue_id)
1335 assert_equal 2, assigns(:prev_issue_id)
1330 assert_equal 5, assigns(:next_issue_id)
1336 assert_equal 5, assigns(:next_issue_id)
1331
1337
1332 count = Issue.open.visible.count
1338 count = Issue.open.visible.count
1333
1339
1334 assert_select 'div.next-prev-links' do
1340 assert_select 'div.next-prev-links' do
1335 assert_select 'a[href="/issues/2"]', :text => /Previous/
1341 assert_select 'a[href="/issues/2"]', :text => /Previous/
1336 assert_select 'a[href="/issues/5"]', :text => /Next/
1342 assert_select 'a[href="/issues/5"]', :text => /Next/
1337 assert_select 'span.position', :text => "3 of #{count}"
1343 assert_select 'span.position', :text => "3 of #{count}"
1338 end
1344 end
1339 end
1345 end
1340
1346
1341 def test_show_should_display_prev_next_links_with_saved_query_in_session
1347 def test_show_should_display_prev_next_links_with_saved_query_in_session
1342 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
1348 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
1343 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1349 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1344 :sort_criteria => [['id', 'asc']])
1350 :sort_criteria => [['id', 'asc']])
1345 @request.session[:query] = {:id => query.id, :project_id => nil}
1351 @request.session[:query] = {:id => query.id, :project_id => nil}
1346
1352
1347 get :show, :id => 11
1353 get :show, :id => 11
1348
1354
1349 assert_response :success
1355 assert_response :success
1350 assert_equal query, assigns(:query)
1356 assert_equal query, assigns(:query)
1351 # Previous and next issues for all projects
1357 # Previous and next issues for all projects
1352 assert_equal 8, assigns(:prev_issue_id)
1358 assert_equal 8, assigns(:prev_issue_id)
1353 assert_equal 12, assigns(:next_issue_id)
1359 assert_equal 12, assigns(:next_issue_id)
1354
1360
1355 assert_select 'div.next-prev-links' do
1361 assert_select 'div.next-prev-links' do
1356 assert_select 'a[href="/issues/8"]', :text => /Previous/
1362 assert_select 'a[href="/issues/8"]', :text => /Previous/
1357 assert_select 'a[href="/issues/12"]', :text => /Next/
1363 assert_select 'a[href="/issues/12"]', :text => /Next/
1358 end
1364 end
1359 end
1365 end
1360
1366
1361 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1367 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1362 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1368 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1363
1369
1364 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1370 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1365 @request.session['issues_index_sort'] = assoc_sort
1371 @request.session['issues_index_sort'] = assoc_sort
1366
1372
1367 get :show, :id => 3
1373 get :show, :id => 3
1368 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1374 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1369
1375
1370 assert_select 'div.next-prev-links' do
1376 assert_select 'div.next-prev-links' do
1371 assert_select 'a', :text => /(Previous|Next)/
1377 assert_select 'a', :text => /(Previous|Next)/
1372 end
1378 end
1373 end
1379 end
1374 end
1380 end
1375
1381
1376 def test_show_should_display_prev_next_links_with_project_query_in_session
1382 def test_show_should_display_prev_next_links_with_project_query_in_session
1377 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1383 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1378 @request.session['issues_index_sort'] = 'id'
1384 @request.session['issues_index_sort'] = 'id'
1379
1385
1380 with_settings :display_subprojects_issues => '0' do
1386 with_settings :display_subprojects_issues => '0' do
1381 get :show, :id => 3
1387 get :show, :id => 3
1382 end
1388 end
1383
1389
1384 assert_response :success
1390 assert_response :success
1385 # Previous and next issues inside project
1391 # Previous and next issues inside project
1386 assert_equal 2, assigns(:prev_issue_id)
1392 assert_equal 2, assigns(:prev_issue_id)
1387 assert_equal 7, assigns(:next_issue_id)
1393 assert_equal 7, assigns(:next_issue_id)
1388
1394
1389 assert_select 'div.next-prev-links' do
1395 assert_select 'div.next-prev-links' do
1390 assert_select 'a[href="/issues/2"]', :text => /Previous/
1396 assert_select 'a[href="/issues/2"]', :text => /Previous/
1391 assert_select 'a[href="/issues/7"]', :text => /Next/
1397 assert_select 'a[href="/issues/7"]', :text => /Next/
1392 end
1398 end
1393 end
1399 end
1394
1400
1395 def test_show_should_not_display_prev_link_for_first_issue
1401 def test_show_should_not_display_prev_link_for_first_issue
1396 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1402 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1397 @request.session['issues_index_sort'] = 'id'
1403 @request.session['issues_index_sort'] = 'id'
1398
1404
1399 with_settings :display_subprojects_issues => '0' do
1405 with_settings :display_subprojects_issues => '0' do
1400 get :show, :id => 1
1406 get :show, :id => 1
1401 end
1407 end
1402
1408
1403 assert_response :success
1409 assert_response :success
1404 assert_nil assigns(:prev_issue_id)
1410 assert_nil assigns(:prev_issue_id)
1405 assert_equal 2, assigns(:next_issue_id)
1411 assert_equal 2, assigns(:next_issue_id)
1406
1412
1407 assert_select 'div.next-prev-links' do
1413 assert_select 'div.next-prev-links' do
1408 assert_select 'a', :text => /Previous/, :count => 0
1414 assert_select 'a', :text => /Previous/, :count => 0
1409 assert_select 'a[href="/issues/2"]', :text => /Next/
1415 assert_select 'a[href="/issues/2"]', :text => /Next/
1410 end
1416 end
1411 end
1417 end
1412
1418
1413 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1419 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1414 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1420 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1415 @request.session['issues_index_sort'] = 'id'
1421 @request.session['issues_index_sort'] = 'id'
1416
1422
1417 get :show, :id => 1
1423 get :show, :id => 1
1418
1424
1419 assert_response :success
1425 assert_response :success
1420 assert_nil assigns(:prev_issue_id)
1426 assert_nil assigns(:prev_issue_id)
1421 assert_nil assigns(:next_issue_id)
1427 assert_nil assigns(:next_issue_id)
1422
1428
1423 assert_select 'a', :text => /Previous/, :count => 0
1429 assert_select 'a', :text => /Previous/, :count => 0
1424 assert_select 'a', :text => /Next/, :count => 0
1430 assert_select 'a', :text => /Next/, :count => 0
1425 end
1431 end
1426
1432
1427 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1433 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1428 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1434 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1429 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1435 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1430 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1436 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1431 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1437 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1432 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1438 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1433
1439
1434 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
1440 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
1435 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1441 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1436 @request.session[:query] = {:id => query.id, :project_id => nil}
1442 @request.session[:query] = {:id => query.id, :project_id => nil}
1437
1443
1438 get :show, :id => 3
1444 get :show, :id => 3
1439 assert_response :success
1445 assert_response :success
1440
1446
1441 assert_equal 2, assigns(:prev_issue_id)
1447 assert_equal 2, assigns(:prev_issue_id)
1442 assert_equal 1, assigns(:next_issue_id)
1448 assert_equal 1, assigns(:next_issue_id)
1443
1449
1444 assert_select 'div.next-prev-links' do
1450 assert_select 'div.next-prev-links' do
1445 assert_select 'a[href="/issues/2"]', :text => /Previous/
1451 assert_select 'a[href="/issues/2"]', :text => /Previous/
1446 assert_select 'a[href="/issues/1"]', :text => /Next/
1452 assert_select 'a[href="/issues/1"]', :text => /Next/
1447 end
1453 end
1448 end
1454 end
1449
1455
1450 def test_show_should_display_prev_next_links_when_request_has_previous_and_next_issue_ids_params
1456 def test_show_should_display_prev_next_links_when_request_has_previous_and_next_issue_ids_params
1451 get :show, :id => 1, :prev_issue_id => 1, :next_issue_id => 3, :issue_position => 2, :issue_count => 4
1457 get :show, :id => 1, :prev_issue_id => 1, :next_issue_id => 3, :issue_position => 2, :issue_count => 4
1452 assert_response :success
1458 assert_response :success
1453
1459
1454 assert_select 'div.next-prev-links' do
1460 assert_select 'div.next-prev-links' do
1455 assert_select 'a[href="/issues/1"]', :text => /Previous/
1461 assert_select 'a[href="/issues/1"]', :text => /Previous/
1456 assert_select 'a[href="/issues/3"]', :text => /Next/
1462 assert_select 'a[href="/issues/3"]', :text => /Next/
1457 assert_select 'span.position', :text => "2 of 4"
1463 assert_select 'span.position', :text => "2 of 4"
1458 end
1464 end
1459 end
1465 end
1460
1466
1461 def test_show_should_display_category_field_if_categories_are_defined
1467 def test_show_should_display_category_field_if_categories_are_defined
1462 Issue.update_all :category_id => nil
1468 Issue.update_all :category_id => nil
1463
1469
1464 get :show, :id => 1
1470 get :show, :id => 1
1465 assert_response :success
1471 assert_response :success
1466 assert_select '.attributes .category'
1472 assert_select '.attributes .category'
1467 end
1473 end
1468
1474
1469 def test_show_should_not_display_category_field_if_no_categories_are_defined
1475 def test_show_should_not_display_category_field_if_no_categories_are_defined
1470 Project.find(1).issue_categories.delete_all
1476 Project.find(1).issue_categories.delete_all
1471
1477
1472 get :show, :id => 1
1478 get :show, :id => 1
1473 assert_response :success
1479 assert_response :success
1474 assert_select 'table.attributes .category', 0
1480 assert_select 'table.attributes .category', 0
1475 end
1481 end
1476
1482
1477 def test_show_should_display_link_to_the_assignee
1483 def test_show_should_display_link_to_the_assignee
1478 get :show, :id => 2
1484 get :show, :id => 2
1479 assert_response :success
1485 assert_response :success
1480 assert_select '.assigned-to' do
1486 assert_select '.assigned-to' do
1481 assert_select 'a[href="/users/3"]'
1487 assert_select 'a[href="/users/3"]'
1482 end
1488 end
1483 end
1489 end
1484
1490
1485 def test_show_should_display_visible_changesets_from_other_projects
1491 def test_show_should_display_visible_changesets_from_other_projects
1486 project = Project.find(2)
1492 project = Project.find(2)
1487 issue = project.issues.first
1493 issue = project.issues.first
1488 issue.changeset_ids = [102]
1494 issue.changeset_ids = [102]
1489 issue.save!
1495 issue.save!
1490 # changesets from other projects should be displayed even if repository
1496 # changesets from other projects should be displayed even if repository
1491 # is disabled on issue's project
1497 # is disabled on issue's project
1492 project.disable_module! :repository
1498 project.disable_module! :repository
1493
1499
1494 @request.session[:user_id] = 2
1500 @request.session[:user_id] = 2
1495 get :show, :id => issue.id
1501 get :show, :id => issue.id
1496
1502
1497 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1503 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1498 end
1504 end
1499
1505
1500 def test_show_should_display_watchers
1506 def test_show_should_display_watchers
1501 @request.session[:user_id] = 2
1507 @request.session[:user_id] = 2
1502 Issue.find(1).add_watcher User.find(2)
1508 Issue.find(1).add_watcher User.find(2)
1503
1509
1504 get :show, :id => 1
1510 get :show, :id => 1
1505 assert_select 'div#watchers ul' do
1511 assert_select 'div#watchers ul' do
1506 assert_select 'li' do
1512 assert_select 'li' do
1507 assert_select 'a[href="/users/2"]'
1513 assert_select 'a[href="/users/2"]'
1508 assert_select 'a[class*=delete]'
1514 assert_select 'a[class*=delete]'
1509 end
1515 end
1510 end
1516 end
1511 end
1517 end
1512
1518
1513 def test_show_should_display_watchers_with_gravatars
1519 def test_show_should_display_watchers_with_gravatars
1514 @request.session[:user_id] = 2
1520 @request.session[:user_id] = 2
1515 Issue.find(1).add_watcher User.find(2)
1521 Issue.find(1).add_watcher User.find(2)
1516
1522
1517 with_settings :gravatar_enabled => '1' do
1523 with_settings :gravatar_enabled => '1' do
1518 get :show, :id => 1
1524 get :show, :id => 1
1519 end
1525 end
1520
1526
1521 assert_select 'div#watchers ul' do
1527 assert_select 'div#watchers ul' do
1522 assert_select 'li' do
1528 assert_select 'li' do
1523 assert_select 'img.gravatar'
1529 assert_select 'img.gravatar'
1524 assert_select 'a[href="/users/2"]'
1530 assert_select 'a[href="/users/2"]'
1525 assert_select 'a[class*=delete]'
1531 assert_select 'a[class*=delete]'
1526 end
1532 end
1527 end
1533 end
1528 end
1534 end
1529
1535
1530 def test_show_with_thumbnails_enabled_should_display_thumbnails
1536 def test_show_with_thumbnails_enabled_should_display_thumbnails
1531 @request.session[:user_id] = 2
1537 @request.session[:user_id] = 2
1532
1538
1533 with_settings :thumbnails_enabled => '1' do
1539 with_settings :thumbnails_enabled => '1' do
1534 get :show, :id => 14
1540 get :show, :id => 14
1535 assert_response :success
1541 assert_response :success
1536 end
1542 end
1537
1543
1538 assert_select 'div.thumbnails' do
1544 assert_select 'div.thumbnails' do
1539 assert_select 'a[href="/attachments/16/testfile.png"]' do
1545 assert_select 'a[href="/attachments/16/testfile.png"]' do
1540 assert_select 'img[src="/attachments/thumbnail/16"]'
1546 assert_select 'img[src="/attachments/thumbnail/16"]'
1541 end
1547 end
1542 end
1548 end
1543 end
1549 end
1544
1550
1545 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1551 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1546 @request.session[:user_id] = 2
1552 @request.session[:user_id] = 2
1547
1553
1548 with_settings :thumbnails_enabled => '0' do
1554 with_settings :thumbnails_enabled => '0' do
1549 get :show, :id => 14
1555 get :show, :id => 14
1550 assert_response :success
1556 assert_response :success
1551 end
1557 end
1552
1558
1553 assert_select 'div.thumbnails', 0
1559 assert_select 'div.thumbnails', 0
1554 end
1560 end
1555
1561
1556 def test_show_with_multi_custom_field
1562 def test_show_with_multi_custom_field
1557 field = CustomField.find(1)
1563 field = CustomField.find(1)
1558 field.update_attribute :multiple, true
1564 field.update_attribute :multiple, true
1559 issue = Issue.find(1)
1565 issue = Issue.find(1)
1560 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1566 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1561 issue.save!
1567 issue.save!
1562
1568
1563 get :show, :id => 1
1569 get :show, :id => 1
1564 assert_response :success
1570 assert_response :success
1565
1571
1566 assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
1572 assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
1567 end
1573 end
1568
1574
1569 def test_show_with_multi_user_custom_field
1575 def test_show_with_multi_user_custom_field
1570 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1576 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1571 :tracker_ids => [1], :is_for_all => true)
1577 :tracker_ids => [1], :is_for_all => true)
1572 issue = Issue.find(1)
1578 issue = Issue.find(1)
1573 issue.custom_field_values = {field.id => ['2', '3']}
1579 issue.custom_field_values = {field.id => ['2', '3']}
1574 issue.save!
1580 issue.save!
1575
1581
1576 get :show, :id => 1
1582 get :show, :id => 1
1577 assert_response :success
1583 assert_response :success
1578
1584
1579 assert_select ".cf_#{field.id} .value", :text => 'Dave Lopper, John Smith' do
1585 assert_select ".cf_#{field.id} .value", :text => 'Dave Lopper, John Smith' do
1580 assert_select 'a', :text => 'Dave Lopper'
1586 assert_select 'a', :text => 'Dave Lopper'
1581 assert_select 'a', :text => 'John Smith'
1587 assert_select 'a', :text => 'John Smith'
1582 end
1588 end
1583 end
1589 end
1584
1590
1585 def test_show_should_display_private_notes_with_permission_only
1591 def test_show_should_display_private_notes_with_permission_only
1586 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1592 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1587 @request.session[:user_id] = 2
1593 @request.session[:user_id] = 2
1588
1594
1589 get :show, :id => 2
1595 get :show, :id => 2
1590 assert_response :success
1596 assert_response :success
1591 assert_include journal, assigns(:journals)
1597 assert_include journal, assigns(:journals)
1592
1598
1593 Role.find(1).remove_permission! :view_private_notes
1599 Role.find(1).remove_permission! :view_private_notes
1594 get :show, :id => 2
1600 get :show, :id => 2
1595 assert_response :success
1601 assert_response :success
1596 assert_not_include journal, assigns(:journals)
1602 assert_not_include journal, assigns(:journals)
1597 end
1603 end
1598
1604
1599 def test_show_atom
1605 def test_show_atom
1600 get :show, :id => 2, :format => 'atom'
1606 get :show, :id => 2, :format => 'atom'
1601 assert_response :success
1607 assert_response :success
1602 assert_template 'journals/index'
1608 assert_template 'journals/index'
1603 # Inline image
1609 # Inline image
1604 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1610 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1605 end
1611 end
1606
1612
1607 def test_show_export_to_pdf
1613 def test_show_export_to_pdf
1608 issue = Issue.find(3)
1614 issue = Issue.find(3)
1609 assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
1615 assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
1610 get :show, :id => 3, :format => 'pdf'
1616 get :show, :id => 3, :format => 'pdf'
1611 assert_response :success
1617 assert_response :success
1612 assert_equal 'application/pdf', @response.content_type
1618 assert_equal 'application/pdf', @response.content_type
1613 assert @response.body.starts_with?('%PDF')
1619 assert @response.body.starts_with?('%PDF')
1614 assert_not_nil assigns(:issue)
1620 assert_not_nil assigns(:issue)
1615 end
1621 end
1616
1622
1617 def test_export_to_pdf_with_utf8_u_fffd
1623 def test_export_to_pdf_with_utf8_u_fffd
1618 # U+FFFD
1624 # U+FFFD
1619 s = "\xef\xbf\xbd"
1625 s = "\xef\xbf\xbd"
1620 s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
1626 s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
1621 issue = Issue.generate!(:subject => s)
1627 issue = Issue.generate!(:subject => s)
1622 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
1628 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
1623 with_settings :default_language => lang do
1629 with_settings :default_language => lang do
1624 get :show, :id => issue.id, :format => 'pdf'
1630 get :show, :id => issue.id, :format => 'pdf'
1625 assert_response :success
1631 assert_response :success
1626 assert_equal 'application/pdf', @response.content_type
1632 assert_equal 'application/pdf', @response.content_type
1627 assert @response.body.starts_with?('%PDF')
1633 assert @response.body.starts_with?('%PDF')
1628 assert_not_nil assigns(:issue)
1634 assert_not_nil assigns(:issue)
1629 end
1635 end
1630 end
1636 end
1631 end
1637 end
1632
1638
1633 def test_show_export_to_pdf_with_ancestors
1639 def test_show_export_to_pdf_with_ancestors
1634 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1640 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1635
1641
1636 get :show, :id => issue.id, :format => 'pdf'
1642 get :show, :id => issue.id, :format => 'pdf'
1637 assert_response :success
1643 assert_response :success
1638 assert_equal 'application/pdf', @response.content_type
1644 assert_equal 'application/pdf', @response.content_type
1639 assert @response.body.starts_with?('%PDF')
1645 assert @response.body.starts_with?('%PDF')
1640 end
1646 end
1641
1647
1642 def test_show_export_to_pdf_with_descendants
1648 def test_show_export_to_pdf_with_descendants
1643 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1649 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1644 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1650 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1645 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1651 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1646
1652
1647 get :show, :id => 1, :format => 'pdf'
1653 get :show, :id => 1, :format => 'pdf'
1648 assert_response :success
1654 assert_response :success
1649 assert_equal 'application/pdf', @response.content_type
1655 assert_equal 'application/pdf', @response.content_type
1650 assert @response.body.starts_with?('%PDF')
1656 assert @response.body.starts_with?('%PDF')
1651 end
1657 end
1652
1658
1653 def test_show_export_to_pdf_with_journals
1659 def test_show_export_to_pdf_with_journals
1654 get :show, :id => 1, :format => 'pdf'
1660 get :show, :id => 1, :format => 'pdf'
1655 assert_response :success
1661 assert_response :success
1656 assert_equal 'application/pdf', @response.content_type
1662 assert_equal 'application/pdf', @response.content_type
1657 assert @response.body.starts_with?('%PDF')
1663 assert @response.body.starts_with?('%PDF')
1658 end
1664 end
1659
1665
1660 def test_show_export_to_pdf_with_changesets
1666 def test_show_export_to_pdf_with_changesets
1661 [[100], [100, 101], [100, 101, 102]].each do |cs|
1667 [[100], [100, 101], [100, 101, 102]].each do |cs|
1662 issue1 = Issue.find(3)
1668 issue1 = Issue.find(3)
1663 issue1.changesets = Changeset.find(cs)
1669 issue1.changesets = Changeset.find(cs)
1664 issue1.save!
1670 issue1.save!
1665 issue = Issue.find(3)
1671 issue = Issue.find(3)
1666 assert_equal issue.changesets.count, cs.size
1672 assert_equal issue.changesets.count, cs.size
1667 get :show, :id => 3, :format => 'pdf'
1673 get :show, :id => 3, :format => 'pdf'
1668 assert_response :success
1674 assert_response :success
1669 assert_equal 'application/pdf', @response.content_type
1675 assert_equal 'application/pdf', @response.content_type
1670 assert @response.body.starts_with?('%PDF')
1676 assert @response.body.starts_with?('%PDF')
1671 end
1677 end
1672 end
1678 end
1673
1679
1674 def test_show_invalid_should_respond_with_404
1680 def test_show_invalid_should_respond_with_404
1675 get :show, :id => 999
1681 get :show, :id => 999
1676 assert_response 404
1682 assert_response 404
1677 end
1683 end
1678
1684
1679 def test_get_new
1685 def test_get_new
1680 @request.session[:user_id] = 2
1686 @request.session[:user_id] = 2
1681 get :new, :project_id => 1, :tracker_id => 1
1687 get :new, :project_id => 1, :tracker_id => 1
1682 assert_response :success
1688 assert_response :success
1683 assert_template 'new'
1689 assert_template 'new'
1684
1690
1685 assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
1691 assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
1686 assert_select 'form#issue-form' do
1692 assert_select 'form#issue-form' do
1687 assert_select 'input[name=?]', 'issue[is_private]'
1693 assert_select 'input[name=?]', 'issue[is_private]'
1688 assert_select 'select[name=?]', 'issue[project_id]', 0
1694 assert_select 'select[name=?]', 'issue[project_id]', 0
1689 assert_select 'select[name=?]', 'issue[tracker_id]'
1695 assert_select 'select[name=?]', 'issue[tracker_id]'
1690 assert_select 'input[name=?]', 'issue[subject]'
1696 assert_select 'input[name=?]', 'issue[subject]'
1691 assert_select 'textarea[name=?]', 'issue[description]'
1697 assert_select 'textarea[name=?]', 'issue[description]'
1692 assert_select 'select[name=?]', 'issue[status_id]'
1698 assert_select 'select[name=?]', 'issue[status_id]'
1693 assert_select 'select[name=?]', 'issue[priority_id]'
1699 assert_select 'select[name=?]', 'issue[priority_id]'
1694 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1700 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1695 assert_select 'select[name=?]', 'issue[category_id]'
1701 assert_select 'select[name=?]', 'issue[category_id]'
1696 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1702 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1697 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1703 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1698 assert_select 'input[name=?]', 'issue[start_date]'
1704 assert_select 'input[name=?]', 'issue[start_date]'
1699 assert_select 'input[name=?]', 'issue[due_date]'
1705 assert_select 'input[name=?]', 'issue[due_date]'
1700 assert_select 'select[name=?]', 'issue[done_ratio]'
1706 assert_select 'select[name=?]', 'issue[done_ratio]'
1701 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1707 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1702 assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
1708 assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
1703 end
1709 end
1704
1710
1705 # Be sure we don't display inactive IssuePriorities
1711 # Be sure we don't display inactive IssuePriorities
1706 assert ! IssuePriority.find(15).active?
1712 assert ! IssuePriority.find(15).active?
1707 assert_select 'select[name=?]', 'issue[priority_id]' do
1713 assert_select 'select[name=?]', 'issue[priority_id]' do
1708 assert_select 'option[value="15"]', 0
1714 assert_select 'option[value="15"]', 0
1709 end
1715 end
1710 end
1716 end
1711
1717
1712 def test_get_new_with_minimal_permissions
1718 def test_get_new_with_minimal_permissions
1713 Role.find(1).update_attribute :permissions, [:add_issues]
1719 Role.find(1).update_attribute :permissions, [:add_issues]
1714 WorkflowTransition.delete_all :role_id => 1
1720 WorkflowTransition.delete_all :role_id => 1
1715
1721
1716 @request.session[:user_id] = 2
1722 @request.session[:user_id] = 2
1717 get :new, :project_id => 1, :tracker_id => 1
1723 get :new, :project_id => 1, :tracker_id => 1
1718 assert_response :success
1724 assert_response :success
1719 assert_template 'new'
1725 assert_template 'new'
1720
1726
1721 assert_select 'form#issue-form' do
1727 assert_select 'form#issue-form' do
1722 assert_select 'input[name=?]', 'issue[is_private]', 0
1728 assert_select 'input[name=?]', 'issue[is_private]', 0
1723 assert_select 'select[name=?]', 'issue[project_id]', 0
1729 assert_select 'select[name=?]', 'issue[project_id]', 0
1724 assert_select 'select[name=?]', 'issue[tracker_id]'
1730 assert_select 'select[name=?]', 'issue[tracker_id]'
1725 assert_select 'input[name=?]', 'issue[subject]'
1731 assert_select 'input[name=?]', 'issue[subject]'
1726 assert_select 'textarea[name=?]', 'issue[description]'
1732 assert_select 'textarea[name=?]', 'issue[description]'
1727 assert_select 'select[name=?]', 'issue[status_id]'
1733 assert_select 'select[name=?]', 'issue[status_id]'
1728 assert_select 'select[name=?]', 'issue[priority_id]'
1734 assert_select 'select[name=?]', 'issue[priority_id]'
1729 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1735 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1730 assert_select 'select[name=?]', 'issue[category_id]'
1736 assert_select 'select[name=?]', 'issue[category_id]'
1731 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1737 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1732 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1738 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1733 assert_select 'input[name=?]', 'issue[start_date]'
1739 assert_select 'input[name=?]', 'issue[start_date]'
1734 assert_select 'input[name=?]', 'issue[due_date]'
1740 assert_select 'input[name=?]', 'issue[due_date]'
1735 assert_select 'select[name=?]', 'issue[done_ratio]'
1741 assert_select 'select[name=?]', 'issue[done_ratio]'
1736 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1742 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1737 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1743 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1738 end
1744 end
1739 end
1745 end
1740
1746
1741 def test_new_without_project_id
1747 def test_new_without_project_id
1742 @request.session[:user_id] = 2
1748 @request.session[:user_id] = 2
1743 get :new
1749 get :new
1744 assert_response :success
1750 assert_response :success
1745 assert_template 'new'
1751 assert_template 'new'
1746
1752
1747 assert_select 'form#issue-form[action=?]', '/issues'
1753 assert_select 'form#issue-form[action=?]', '/issues'
1748 assert_select 'form#issue-form' do
1754 assert_select 'form#issue-form' do
1749 assert_select 'select[name=?]', 'issue[project_id]'
1755 assert_select 'select[name=?]', 'issue[project_id]'
1750 end
1756 end
1751
1757
1752 assert_nil assigns(:project)
1758 assert_nil assigns(:project)
1753 assert_not_nil assigns(:issue)
1759 assert_not_nil assigns(:issue)
1754 end
1760 end
1755
1761
1756 def test_new_should_select_default_status
1762 def test_new_should_select_default_status
1757 @request.session[:user_id] = 2
1763 @request.session[:user_id] = 2
1758
1764
1759 get :new, :project_id => 1
1765 get :new, :project_id => 1
1760 assert_response :success
1766 assert_response :success
1761 assert_template 'new'
1767 assert_template 'new'
1762 assert_select 'select[name=?]', 'issue[status_id]' do
1768 assert_select 'select[name=?]', 'issue[status_id]' do
1763 assert_select 'option[value="1"][selected=selected]'
1769 assert_select 'option[value="1"][selected=selected]'
1764 end
1770 end
1765 assert_select 'input[name=was_default_status][value="1"]'
1771 assert_select 'input[name=was_default_status][value="1"]'
1766 end
1772 end
1767
1773
1768 def test_new_should_propose_allowed_statuses
1774 def test_new_should_propose_allowed_statuses
1769 WorkflowTransition.delete_all
1775 WorkflowTransition.delete_all
1770 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 1)
1776 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 1)
1771 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 3)
1777 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 3)
1772 @request.session[:user_id] = 2
1778 @request.session[:user_id] = 2
1773
1779
1774 get :new, :project_id => 1
1780 get :new, :project_id => 1
1775 assert_response :success
1781 assert_response :success
1776 assert_select 'select[name=?]', 'issue[status_id]' do
1782 assert_select 'select[name=?]', 'issue[status_id]' do
1777 assert_select 'option[value="1"]'
1783 assert_select 'option[value="1"]'
1778 assert_select 'option[value="3"]'
1784 assert_select 'option[value="3"]'
1779 assert_select 'option', 2
1785 assert_select 'option', 2
1780 assert_select 'option[value="1"][selected=selected]'
1786 assert_select 'option[value="1"][selected=selected]'
1781 end
1787 end
1782 end
1788 end
1783
1789
1784 def test_new_should_propose_allowed_statuses_without_default_status_allowed
1790 def test_new_should_propose_allowed_statuses_without_default_status_allowed
1785 WorkflowTransition.delete_all
1791 WorkflowTransition.delete_all
1786 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 2)
1792 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 2)
1787 assert_equal 1, Tracker.find(1).default_status_id
1793 assert_equal 1, Tracker.find(1).default_status_id
1788 @request.session[:user_id] = 2
1794 @request.session[:user_id] = 2
1789
1795
1790 get :new, :project_id => 1
1796 get :new, :project_id => 1
1791 assert_response :success
1797 assert_response :success
1792 assert_select 'select[name=?]', 'issue[status_id]' do
1798 assert_select 'select[name=?]', 'issue[status_id]' do
1793 assert_select 'option[value="2"]'
1799 assert_select 'option[value="2"]'
1794 assert_select 'option', 1
1800 assert_select 'option', 1
1795 assert_select 'option[value="2"][selected=selected]'
1801 assert_select 'option[value="2"][selected=selected]'
1796 end
1802 end
1797 end
1803 end
1798
1804
1799 def test_new_should_preselect_default_version
1805 def test_new_should_preselect_default_version
1800 version = Version.generate!(:project_id => 1)
1806 version = Version.generate!(:project_id => 1)
1801 Project.find(1).update_attribute :default_version_id, version.id
1807 Project.find(1).update_attribute :default_version_id, version.id
1802 @request.session[:user_id] = 2
1808 @request.session[:user_id] = 2
1803
1809
1804 get :new, :project_id => 1
1810 get :new, :project_id => 1
1805 assert_response :success
1811 assert_response :success
1806 assert_equal version, assigns(:issue).fixed_version
1812 assert_equal version, assigns(:issue).fixed_version
1807 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
1813 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
1808 assert_select 'option[value=?][selected=selected]', version.id.to_s
1814 assert_select 'option[value=?][selected=selected]', version.id.to_s
1809 end
1815 end
1810 end
1816 end
1811
1817
1812 def test_get_new_with_list_custom_field
1818 def test_get_new_with_list_custom_field
1813 @request.session[:user_id] = 2
1819 @request.session[:user_id] = 2
1814 get :new, :project_id => 1, :tracker_id => 1
1820 get :new, :project_id => 1, :tracker_id => 1
1815 assert_response :success
1821 assert_response :success
1816 assert_template 'new'
1822 assert_template 'new'
1817
1823
1818 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1824 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1819 assert_select 'option', 4
1825 assert_select 'option', 4
1820 assert_select 'option[value=MySQL]', :text => 'MySQL'
1826 assert_select 'option[value=MySQL]', :text => 'MySQL'
1821 end
1827 end
1822 end
1828 end
1823
1829
1824 def test_get_new_with_multi_custom_field
1830 def test_get_new_with_multi_custom_field
1825 field = IssueCustomField.find(1)
1831 field = IssueCustomField.find(1)
1826 field.update_attribute :multiple, true
1832 field.update_attribute :multiple, true
1827
1833
1828 @request.session[:user_id] = 2
1834 @request.session[:user_id] = 2
1829 get :new, :project_id => 1, :tracker_id => 1
1835 get :new, :project_id => 1, :tracker_id => 1
1830 assert_response :success
1836 assert_response :success
1831 assert_template 'new'
1837 assert_template 'new'
1832
1838
1833 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1839 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1834 assert_select 'option', 3
1840 assert_select 'option', 3
1835 assert_select 'option[value=MySQL]', :text => 'MySQL'
1841 assert_select 'option[value=MySQL]', :text => 'MySQL'
1836 end
1842 end
1837 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1843 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1838 end
1844 end
1839
1845
1840 def test_get_new_with_multi_user_custom_field
1846 def test_get_new_with_multi_user_custom_field
1841 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1847 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1842 :tracker_ids => [1], :is_for_all => true)
1848 :tracker_ids => [1], :is_for_all => true)
1843
1849
1844 @request.session[:user_id] = 2
1850 @request.session[:user_id] = 2
1845 get :new, :project_id => 1, :tracker_id => 1
1851 get :new, :project_id => 1, :tracker_id => 1
1846 assert_response :success
1852 assert_response :success
1847 assert_template 'new'
1853 assert_template 'new'
1848
1854
1849 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1855 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1850 assert_select 'option', Project.find(1).users.count
1856 assert_select 'option', Project.find(1).users.count
1851 assert_select 'option[value="2"]', :text => 'John Smith'
1857 assert_select 'option[value="2"]', :text => 'John Smith'
1852 end
1858 end
1853 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1859 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1854 end
1860 end
1855
1861
1856 def test_get_new_with_date_custom_field
1862 def test_get_new_with_date_custom_field
1857 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1863 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1858
1864
1859 @request.session[:user_id] = 2
1865 @request.session[:user_id] = 2
1860 get :new, :project_id => 1, :tracker_id => 1
1866 get :new, :project_id => 1, :tracker_id => 1
1861 assert_response :success
1867 assert_response :success
1862
1868
1863 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1869 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1864 end
1870 end
1865
1871
1866 def test_get_new_with_text_custom_field
1872 def test_get_new_with_text_custom_field
1867 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1873 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1868
1874
1869 @request.session[:user_id] = 2
1875 @request.session[:user_id] = 2
1870 get :new, :project_id => 1, :tracker_id => 1
1876 get :new, :project_id => 1, :tracker_id => 1
1871 assert_response :success
1877 assert_response :success
1872
1878
1873 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1879 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1874 end
1880 end
1875
1881
1876 def test_get_new_without_default_start_date_is_creation_date
1882 def test_get_new_without_default_start_date_is_creation_date
1877 with_settings :default_issue_start_date_to_creation_date => 0 do
1883 with_settings :default_issue_start_date_to_creation_date => 0 do
1878 @request.session[:user_id] = 2
1884 @request.session[:user_id] = 2
1879 get :new, :project_id => 1, :tracker_id => 1
1885 get :new, :project_id => 1, :tracker_id => 1
1880 assert_response :success
1886 assert_response :success
1881 assert_template 'new'
1887 assert_template 'new'
1882 assert_select 'input[name=?]', 'issue[start_date]'
1888 assert_select 'input[name=?]', 'issue[start_date]'
1883 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1889 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1884 end
1890 end
1885 end
1891 end
1886
1892
1887 def test_get_new_with_default_start_date_is_creation_date
1893 def test_get_new_with_default_start_date_is_creation_date
1888 with_settings :default_issue_start_date_to_creation_date => 1 do
1894 with_settings :default_issue_start_date_to_creation_date => 1 do
1889 @request.session[:user_id] = 2
1895 @request.session[:user_id] = 2
1890 get :new, :project_id => 1, :tracker_id => 1
1896 get :new, :project_id => 1, :tracker_id => 1
1891 assert_response :success
1897 assert_response :success
1892 assert_template 'new'
1898 assert_template 'new'
1893 assert_select 'input[name=?][value=?]', 'issue[start_date]',
1899 assert_select 'input[name=?][value=?]', 'issue[start_date]',
1894 Date.today.to_s
1900 Date.today.to_s
1895 end
1901 end
1896 end
1902 end
1897
1903
1898 def test_get_new_form_should_allow_attachment_upload
1904 def test_get_new_form_should_allow_attachment_upload
1899 @request.session[:user_id] = 2
1905 @request.session[:user_id] = 2
1900 get :new, :project_id => 1, :tracker_id => 1
1906 get :new, :project_id => 1, :tracker_id => 1
1901
1907
1902 assert_select 'form[id=issue-form][method=post][enctype="multipart/form-data"]' do
1908 assert_select 'form[id=issue-form][method=post][enctype="multipart/form-data"]' do
1903 assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
1909 assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
1904 end
1910 end
1905 end
1911 end
1906
1912
1907 def test_get_new_should_prefill_the_form_from_params
1913 def test_get_new_should_prefill_the_form_from_params
1908 @request.session[:user_id] = 2
1914 @request.session[:user_id] = 2
1909 get :new, :project_id => 1,
1915 get :new, :project_id => 1,
1910 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1916 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1911
1917
1912 issue = assigns(:issue)
1918 issue = assigns(:issue)
1913 assert_equal 3, issue.tracker_id
1919 assert_equal 3, issue.tracker_id
1914 assert_equal 'Prefilled', issue.description
1920 assert_equal 'Prefilled', issue.description
1915 assert_equal 'Custom field value', issue.custom_field_value(2)
1921 assert_equal 'Custom field value', issue.custom_field_value(2)
1916
1922
1917 assert_select 'select[name=?]', 'issue[tracker_id]' do
1923 assert_select 'select[name=?]', 'issue[tracker_id]' do
1918 assert_select 'option[value="3"][selected=selected]'
1924 assert_select 'option[value="3"][selected=selected]'
1919 end
1925 end
1920 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1926 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1921 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1927 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1922 end
1928 end
1923
1929
1924 def test_get_new_should_mark_required_fields
1930 def test_get_new_should_mark_required_fields
1925 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1931 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1926 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1932 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1927 WorkflowPermission.delete_all
1933 WorkflowPermission.delete_all
1928 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1934 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1929 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1935 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1930 @request.session[:user_id] = 2
1936 @request.session[:user_id] = 2
1931
1937
1932 get :new, :project_id => 1
1938 get :new, :project_id => 1
1933 assert_response :success
1939 assert_response :success
1934 assert_template 'new'
1940 assert_template 'new'
1935
1941
1936 assert_select 'label[for=issue_start_date]' do
1942 assert_select 'label[for=issue_start_date]' do
1937 assert_select 'span[class=required]', 0
1943 assert_select 'span[class=required]', 0
1938 end
1944 end
1939 assert_select 'label[for=issue_due_date]' do
1945 assert_select 'label[for=issue_due_date]' do
1940 assert_select 'span[class=required]'
1946 assert_select 'span[class=required]'
1941 end
1947 end
1942 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1948 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1943 assert_select 'span[class=required]', 0
1949 assert_select 'span[class=required]', 0
1944 end
1950 end
1945 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1951 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1946 assert_select 'span[class=required]'
1952 assert_select 'span[class=required]'
1947 end
1953 end
1948 end
1954 end
1949
1955
1950 def test_get_new_should_not_display_readonly_fields
1956 def test_get_new_should_not_display_readonly_fields
1951 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1957 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1952 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1958 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1953 WorkflowPermission.delete_all
1959 WorkflowPermission.delete_all
1954 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1960 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1955 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1961 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1956 @request.session[:user_id] = 2
1962 @request.session[:user_id] = 2
1957
1963
1958 get :new, :project_id => 1
1964 get :new, :project_id => 1
1959 assert_response :success
1965 assert_response :success
1960 assert_template 'new'
1966 assert_template 'new'
1961
1967
1962 assert_select 'input[name=?]', 'issue[start_date]'
1968 assert_select 'input[name=?]', 'issue[start_date]'
1963 assert_select 'input[name=?]', 'issue[due_date]', 0
1969 assert_select 'input[name=?]', 'issue[due_date]', 0
1964 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1970 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1965 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1971 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1966 end
1972 end
1967
1973
1968 def test_new_with_tracker_set_as_readonly_should_accept_status
1974 def test_new_with_tracker_set_as_readonly_should_accept_status
1969 WorkflowPermission.delete_all
1975 WorkflowPermission.delete_all
1970 [1, 2].each do |status_id|
1976 [1, 2].each do |status_id|
1971 WorkflowPermission.create!(:tracker_id => 1, :old_status_id => status_id, :role_id => 1, :field_name => 'tracker_id', :rule => 'readonly')
1977 WorkflowPermission.create!(:tracker_id => 1, :old_status_id => status_id, :role_id => 1, :field_name => 'tracker_id', :rule => 'readonly')
1972 end
1978 end
1973 @request.session[:user_id] = 2
1979 @request.session[:user_id] = 2
1974
1980
1975 get :new, :project_id => 1, :issue => {:status_id => 2}
1981 get :new, :project_id => 1, :issue => {:status_id => 2}
1976 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1982 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1977 assert_equal 2, assigns(:issue).status_id
1983 assert_equal 2, assigns(:issue).status_id
1978 end
1984 end
1979
1985
1980 def test_get_new_without_tracker_id
1986 def test_get_new_without_tracker_id
1981 @request.session[:user_id] = 2
1987 @request.session[:user_id] = 2
1982 get :new, :project_id => 1
1988 get :new, :project_id => 1
1983 assert_response :success
1989 assert_response :success
1984 assert_template 'new'
1990 assert_template 'new'
1985
1991
1986 issue = assigns(:issue)
1992 issue = assigns(:issue)
1987 assert_not_nil issue
1993 assert_not_nil issue
1988 assert_equal Project.find(1).trackers.first, issue.tracker
1994 assert_equal Project.find(1).trackers.first, issue.tracker
1989 end
1995 end
1990
1996
1991 def test_get_new_with_no_default_status_should_display_an_error
1997 def test_get_new_with_no_default_status_should_display_an_error
1992 @request.session[:user_id] = 2
1998 @request.session[:user_id] = 2
1993 IssueStatus.delete_all
1999 IssueStatus.delete_all
1994
2000
1995 get :new, :project_id => 1
2001 get :new, :project_id => 1
1996 assert_response 500
2002 assert_response 500
1997 assert_select_error /No default issue/
2003 assert_select_error /No default issue/
1998 end
2004 end
1999
2005
2000 def test_get_new_with_no_tracker_should_display_an_error
2006 def test_get_new_with_no_tracker_should_display_an_error
2001 @request.session[:user_id] = 2
2007 @request.session[:user_id] = 2
2002 Tracker.delete_all
2008 Tracker.delete_all
2003
2009
2004 get :new, :project_id => 1
2010 get :new, :project_id => 1
2005 assert_response 500
2011 assert_response 500
2006 assert_select_error /No tracker/
2012 assert_select_error /No tracker/
2007 end
2013 end
2008
2014
2009 def test_new_with_invalid_project_id
2015 def test_new_with_invalid_project_id
2010 @request.session[:user_id] = 1
2016 @request.session[:user_id] = 1
2011 get :new, :project_id => 'invalid'
2017 get :new, :project_id => 'invalid'
2012 assert_response 404
2018 assert_response 404
2013 end
2019 end
2014
2020
2015 def test_update_form_for_new_issue
2021 def test_update_form_for_new_issue
2016 @request.session[:user_id] = 2
2022 @request.session[:user_id] = 2
2017 xhr :post, :new, :project_id => 1,
2023 xhr :post, :new, :project_id => 1,
2018 :issue => {:tracker_id => 2,
2024 :issue => {:tracker_id => 2,
2019 :subject => 'This is the test_new issue',
2025 :subject => 'This is the test_new issue',
2020 :description => 'This is the description',
2026 :description => 'This is the description',
2021 :priority_id => 5}
2027 :priority_id => 5}
2022 assert_response :success
2028 assert_response :success
2023 assert_template 'new'
2029 assert_template 'new'
2024 assert_template :partial => '_form'
2030 assert_template :partial => '_form'
2025 assert_equal 'text/javascript', response.content_type
2031 assert_equal 'text/javascript', response.content_type
2026
2032
2027 issue = assigns(:issue)
2033 issue = assigns(:issue)
2028 assert_kind_of Issue, issue
2034 assert_kind_of Issue, issue
2029 assert_equal 1, issue.project_id
2035 assert_equal 1, issue.project_id
2030 assert_equal 2, issue.tracker_id
2036 assert_equal 2, issue.tracker_id
2031 assert_equal 'This is the test_new issue', issue.subject
2037 assert_equal 'This is the test_new issue', issue.subject
2032 end
2038 end
2033
2039
2034 def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
2040 def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
2035 @request.session[:user_id] = 2
2041 @request.session[:user_id] = 2
2036 WorkflowTransition.delete_all
2042 WorkflowTransition.delete_all
2037 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2)
2043 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2)
2038 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 5)
2044 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 5)
2039 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
2045 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
2040
2046
2041 xhr :post, :new, :project_id => 1,
2047 xhr :post, :new, :project_id => 1,
2042 :issue => {:tracker_id => 1,
2048 :issue => {:tracker_id => 1,
2043 :status_id => 5,
2049 :status_id => 5,
2044 :subject => 'This is an issue'}
2050 :subject => 'This is an issue'}
2045
2051
2046 assert_equal 5, assigns(:issue).status_id
2052 assert_equal 5, assigns(:issue).status_id
2047 assert_equal [2,5], assigns(:allowed_statuses).map(&:id).sort
2053 assert_equal [2,5], assigns(:allowed_statuses).map(&:id).sort
2048 end
2054 end
2049
2055
2050 def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals
2056 def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals
2051 @request.session[:user_id] = 2
2057 @request.session[:user_id] = 2
2052 tracker = Tracker.find(2)
2058 tracker = Tracker.find(2)
2053 tracker.update! :default_status_id => 2
2059 tracker.update! :default_status_id => 2
2054 tracker.generate_transitions! 2, 1, :clear => true
2060 tracker.generate_transitions! 2, 1, :clear => true
2055
2061
2056 xhr :post, :new, :project_id => 1,
2062 xhr :post, :new, :project_id => 1,
2057 :issue => {:tracker_id => 2,
2063 :issue => {:tracker_id => 2,
2058 :status_id => 1},
2064 :status_id => 1},
2059 :was_default_status => 1
2065 :was_default_status => 1
2060
2066
2061 assert_equal 2, assigns(:issue).status_id
2067 assert_equal 2, assigns(:issue).status_id
2062 end
2068 end
2063
2069
2064 def test_update_form_for_new_issue_should_ignore_version_when_changing_project
2070 def test_update_form_for_new_issue_should_ignore_version_when_changing_project
2065 version = Version.generate!(:project_id => 1)
2071 version = Version.generate!(:project_id => 1)
2066 Project.find(1).update_attribute :default_version_id, version.id
2072 Project.find(1).update_attribute :default_version_id, version.id
2067 @request.session[:user_id] = 2
2073 @request.session[:user_id] = 2
2068
2074
2069 xhr :post, :new, :issue => {:project_id => 1,
2075 xhr :post, :new, :issue => {:project_id => 1,
2070 :fixed_version_id => ''},
2076 :fixed_version_id => ''},
2071 :form_update_triggered_by => 'issue_project_id'
2077 :form_update_triggered_by => 'issue_project_id'
2072 assert_response :success
2078 assert_response :success
2073 assert_template 'new'
2079 assert_template 'new'
2074
2080
2075 issue = assigns(:issue)
2081 issue = assigns(:issue)
2076 assert_equal 1, issue.project_id
2082 assert_equal 1, issue.project_id
2077 assert_equal version, issue.fixed_version
2083 assert_equal version, issue.fixed_version
2078 end
2084 end
2079
2085
2080 def test_post_create
2086 def test_post_create
2081 @request.session[:user_id] = 2
2087 @request.session[:user_id] = 2
2082 assert_difference 'Issue.count' do
2088 assert_difference 'Issue.count' do
2083 assert_no_difference 'Journal.count' do
2089 assert_no_difference 'Journal.count' do
2084 post :create, :project_id => 1,
2090 post :create, :project_id => 1,
2085 :issue => {:tracker_id => 3,
2091 :issue => {:tracker_id => 3,
2086 :status_id => 2,
2092 :status_id => 2,
2087 :subject => 'This is the test_new issue',
2093 :subject => 'This is the test_new issue',
2088 :description => 'This is the description',
2094 :description => 'This is the description',
2089 :priority_id => 5,
2095 :priority_id => 5,
2090 :start_date => '2010-11-07',
2096 :start_date => '2010-11-07',
2091 :estimated_hours => '',
2097 :estimated_hours => '',
2092 :custom_field_values => {'2' => 'Value for field 2'}}
2098 :custom_field_values => {'2' => 'Value for field 2'}}
2093 end
2099 end
2094 end
2100 end
2095 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2101 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2096
2102
2097 issue = Issue.find_by_subject('This is the test_new issue')
2103 issue = Issue.find_by_subject('This is the test_new issue')
2098 assert_not_nil issue
2104 assert_not_nil issue
2099 assert_equal 2, issue.author_id
2105 assert_equal 2, issue.author_id
2100 assert_equal 3, issue.tracker_id
2106 assert_equal 3, issue.tracker_id
2101 assert_equal 2, issue.status_id
2107 assert_equal 2, issue.status_id
2102 assert_equal Date.parse('2010-11-07'), issue.start_date
2108 assert_equal Date.parse('2010-11-07'), issue.start_date
2103 assert_nil issue.estimated_hours
2109 assert_nil issue.estimated_hours
2104 v = issue.custom_values.where(:custom_field_id => 2).first
2110 v = issue.custom_values.where(:custom_field_id => 2).first
2105 assert_not_nil v
2111 assert_not_nil v
2106 assert_equal 'Value for field 2', v.value
2112 assert_equal 'Value for field 2', v.value
2107 end
2113 end
2108
2114
2109 def test_post_new_with_group_assignment
2115 def test_post_new_with_group_assignment
2110 group = Group.find(11)
2116 group = Group.find(11)
2111 project = Project.find(1)
2117 project = Project.find(1)
2112 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
2118 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
2113
2119
2114 with_settings :issue_group_assignment => '1' do
2120 with_settings :issue_group_assignment => '1' do
2115 @request.session[:user_id] = 2
2121 @request.session[:user_id] = 2
2116 assert_difference 'Issue.count' do
2122 assert_difference 'Issue.count' do
2117 post :create, :project_id => project.id,
2123 post :create, :project_id => project.id,
2118 :issue => {:tracker_id => 3,
2124 :issue => {:tracker_id => 3,
2119 :status_id => 1,
2125 :status_id => 1,
2120 :subject => 'This is the test_new_with_group_assignment issue',
2126 :subject => 'This is the test_new_with_group_assignment issue',
2121 :assigned_to_id => group.id}
2127 :assigned_to_id => group.id}
2122 end
2128 end
2123 end
2129 end
2124 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2130 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2125
2131
2126 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
2132 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
2127 assert_not_nil issue
2133 assert_not_nil issue
2128 assert_equal group, issue.assigned_to
2134 assert_equal group, issue.assigned_to
2129 end
2135 end
2130
2136
2131 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
2137 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
2132 with_settings :default_issue_start_date_to_creation_date => 0 do
2138 with_settings :default_issue_start_date_to_creation_date => 0 do
2133 @request.session[:user_id] = 2
2139 @request.session[:user_id] = 2
2134 assert_difference 'Issue.count' do
2140 assert_difference 'Issue.count' do
2135 post :create, :project_id => 1,
2141 post :create, :project_id => 1,
2136 :issue => {:tracker_id => 3,
2142 :issue => {:tracker_id => 3,
2137 :status_id => 2,
2143 :status_id => 2,
2138 :subject => 'This is the test_new issue',
2144 :subject => 'This is the test_new issue',
2139 :description => 'This is the description',
2145 :description => 'This is the description',
2140 :priority_id => 5,
2146 :priority_id => 5,
2141 :estimated_hours => '',
2147 :estimated_hours => '',
2142 :custom_field_values => {'2' => 'Value for field 2'}}
2148 :custom_field_values => {'2' => 'Value for field 2'}}
2143 end
2149 end
2144 assert_redirected_to :controller => 'issues', :action => 'show',
2150 assert_redirected_to :controller => 'issues', :action => 'show',
2145 :id => Issue.last.id
2151 :id => Issue.last.id
2146 issue = Issue.find_by_subject('This is the test_new issue')
2152 issue = Issue.find_by_subject('This is the test_new issue')
2147 assert_not_nil issue
2153 assert_not_nil issue
2148 assert_nil issue.start_date
2154 assert_nil issue.start_date
2149 end
2155 end
2150 end
2156 end
2151
2157
2152 def test_post_create_without_start_date_and_default_start_date_is_creation_date
2158 def test_post_create_without_start_date_and_default_start_date_is_creation_date
2153 with_settings :default_issue_start_date_to_creation_date => 1 do
2159 with_settings :default_issue_start_date_to_creation_date => 1 do
2154 @request.session[:user_id] = 2
2160 @request.session[:user_id] = 2
2155 assert_difference 'Issue.count' do
2161 assert_difference 'Issue.count' do
2156 post :create, :project_id => 1,
2162 post :create, :project_id => 1,
2157 :issue => {:tracker_id => 3,
2163 :issue => {:tracker_id => 3,
2158 :status_id => 2,
2164 :status_id => 2,
2159 :subject => 'This is the test_new issue',
2165 :subject => 'This is the test_new issue',
2160 :description => 'This is the description',
2166 :description => 'This is the description',
2161 :priority_id => 5,
2167 :priority_id => 5,
2162 :estimated_hours => '',
2168 :estimated_hours => '',
2163 :custom_field_values => {'2' => 'Value for field 2'}}
2169 :custom_field_values => {'2' => 'Value for field 2'}}
2164 end
2170 end
2165 assert_redirected_to :controller => 'issues', :action => 'show',
2171 assert_redirected_to :controller => 'issues', :action => 'show',
2166 :id => Issue.last.id
2172 :id => Issue.last.id
2167 issue = Issue.find_by_subject('This is the test_new issue')
2173 issue = Issue.find_by_subject('This is the test_new issue')
2168 assert_not_nil issue
2174 assert_not_nil issue
2169 assert_equal Date.today, issue.start_date
2175 assert_equal Date.today, issue.start_date
2170 end
2176 end
2171 end
2177 end
2172
2178
2173 def test_post_create_and_continue
2179 def test_post_create_and_continue
2174 @request.session[:user_id] = 2
2180 @request.session[:user_id] = 2
2175 assert_difference 'Issue.count' do
2181 assert_difference 'Issue.count' do
2176 post :create, :project_id => 1,
2182 post :create, :project_id => 1,
2177 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
2183 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
2178 :continue => ''
2184 :continue => ''
2179 end
2185 end
2180
2186
2181 issue = Issue.order('id DESC').first
2187 issue = Issue.order('id DESC').first
2182 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
2188 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
2183 assert_not_nil flash[:notice], "flash was not set"
2189 assert_not_nil flash[:notice], "flash was not set"
2184 assert_select_in flash[:notice],
2190 assert_select_in flash[:notice],
2185 'a[href=?][title=?]', "/issues/#{issue.id}", "This is first issue", :text => "##{issue.id}"
2191 'a[href=?][title=?]', "/issues/#{issue.id}", "This is first issue", :text => "##{issue.id}"
2186 end
2192 end
2187
2193
2188 def test_post_create_without_custom_fields_param
2194 def test_post_create_without_custom_fields_param
2189 @request.session[:user_id] = 2
2195 @request.session[:user_id] = 2
2190 assert_difference 'Issue.count' do
2196 assert_difference 'Issue.count' do
2191 post :create, :project_id => 1,
2197 post :create, :project_id => 1,
2192 :issue => {:tracker_id => 1,
2198 :issue => {:tracker_id => 1,
2193 :subject => 'This is the test_new issue',
2199 :subject => 'This is the test_new issue',
2194 :description => 'This is the description',
2200 :description => 'This is the description',
2195 :priority_id => 5}
2201 :priority_id => 5}
2196 end
2202 end
2197 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2203 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2198 end
2204 end
2199
2205
2200 def test_post_create_with_multi_custom_field
2206 def test_post_create_with_multi_custom_field
2201 field = IssueCustomField.find_by_name('Database')
2207 field = IssueCustomField.find_by_name('Database')
2202 field.update_attribute(:multiple, true)
2208 field.update_attribute(:multiple, true)
2203
2209
2204 @request.session[:user_id] = 2
2210 @request.session[:user_id] = 2
2205 assert_difference 'Issue.count' do
2211 assert_difference 'Issue.count' do
2206 post :create, :project_id => 1,
2212 post :create, :project_id => 1,
2207 :issue => {:tracker_id => 1,
2213 :issue => {:tracker_id => 1,
2208 :subject => 'This is the test_new issue',
2214 :subject => 'This is the test_new issue',
2209 :description => 'This is the description',
2215 :description => 'This is the description',
2210 :priority_id => 5,
2216 :priority_id => 5,
2211 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
2217 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
2212 end
2218 end
2213 assert_response 302
2219 assert_response 302
2214 issue = Issue.order('id DESC').first
2220 issue = Issue.order('id DESC').first
2215 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
2221 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
2216 end
2222 end
2217
2223
2218 def test_post_create_with_empty_multi_custom_field
2224 def test_post_create_with_empty_multi_custom_field
2219 field = IssueCustomField.find_by_name('Database')
2225 field = IssueCustomField.find_by_name('Database')
2220 field.update_attribute(:multiple, true)
2226 field.update_attribute(:multiple, true)
2221
2227
2222 @request.session[:user_id] = 2
2228 @request.session[:user_id] = 2
2223 assert_difference 'Issue.count' do
2229 assert_difference 'Issue.count' do
2224 post :create, :project_id => 1,
2230 post :create, :project_id => 1,
2225 :issue => {:tracker_id => 1,
2231 :issue => {:tracker_id => 1,
2226 :subject => 'This is the test_new issue',
2232 :subject => 'This is the test_new issue',
2227 :description => 'This is the description',
2233 :description => 'This is the description',
2228 :priority_id => 5,
2234 :priority_id => 5,
2229 :custom_field_values => {'1' => ['']}}
2235 :custom_field_values => {'1' => ['']}}
2230 end
2236 end
2231 assert_response 302
2237 assert_response 302
2232 issue = Issue.order('id DESC').first
2238 issue = Issue.order('id DESC').first
2233 assert_equal [''], issue.custom_field_value(1).sort
2239 assert_equal [''], issue.custom_field_value(1).sort
2234 end
2240 end
2235
2241
2236 def test_post_create_with_multi_user_custom_field
2242 def test_post_create_with_multi_user_custom_field
2237 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
2243 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
2238 :tracker_ids => [1], :is_for_all => true)
2244 :tracker_ids => [1], :is_for_all => true)
2239
2245
2240 @request.session[:user_id] = 2
2246 @request.session[:user_id] = 2
2241 assert_difference 'Issue.count' do
2247 assert_difference 'Issue.count' do
2242 post :create, :project_id => 1,
2248 post :create, :project_id => 1,
2243 :issue => {:tracker_id => 1,
2249 :issue => {:tracker_id => 1,
2244 :subject => 'This is the test_new issue',
2250 :subject => 'This is the test_new issue',
2245 :description => 'This is the description',
2251 :description => 'This is the description',
2246 :priority_id => 5,
2252 :priority_id => 5,
2247 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
2253 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
2248 end
2254 end
2249 assert_response 302
2255 assert_response 302
2250 issue = Issue.order('id DESC').first
2256 issue = Issue.order('id DESC').first
2251 assert_equal ['2', '3'], issue.custom_field_value(field).sort
2257 assert_equal ['2', '3'], issue.custom_field_value(field).sort
2252 end
2258 end
2253
2259
2254 def test_post_create_with_required_custom_field_and_without_custom_fields_param
2260 def test_post_create_with_required_custom_field_and_without_custom_fields_param
2255 field = IssueCustomField.find_by_name('Database')
2261 field = IssueCustomField.find_by_name('Database')
2256 field.update_attribute(:is_required, true)
2262 field.update_attribute(:is_required, true)
2257
2263
2258 @request.session[:user_id] = 2
2264 @request.session[:user_id] = 2
2259 assert_no_difference 'Issue.count' do
2265 assert_no_difference 'Issue.count' do
2260 post :create, :project_id => 1,
2266 post :create, :project_id => 1,
2261 :issue => {:tracker_id => 1,
2267 :issue => {:tracker_id => 1,
2262 :subject => 'This is the test_new issue',
2268 :subject => 'This is the test_new issue',
2263 :description => 'This is the description',
2269 :description => 'This is the description',
2264 :priority_id => 5}
2270 :priority_id => 5}
2265 end
2271 end
2266 assert_response :success
2272 assert_response :success
2267 assert_template 'new'
2273 assert_template 'new'
2268 issue = assigns(:issue)
2274 issue = assigns(:issue)
2269 assert_not_nil issue
2275 assert_not_nil issue
2270 assert_select_error /Database cannot be blank/
2276 assert_select_error /Database cannot be blank/
2271 end
2277 end
2272
2278
2273 def test_create_should_validate_required_fields
2279 def test_create_should_validate_required_fields
2274 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2280 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2275 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2281 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2276 WorkflowPermission.delete_all
2282 WorkflowPermission.delete_all
2277 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
2283 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
2278 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2284 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2279 @request.session[:user_id] = 2
2285 @request.session[:user_id] = 2
2280
2286
2281 assert_no_difference 'Issue.count' do
2287 assert_no_difference 'Issue.count' do
2282 post :create, :project_id => 1, :issue => {
2288 post :create, :project_id => 1, :issue => {
2283 :tracker_id => 2,
2289 :tracker_id => 2,
2284 :status_id => 1,
2290 :status_id => 1,
2285 :subject => 'Test',
2291 :subject => 'Test',
2286 :start_date => '',
2292 :start_date => '',
2287 :due_date => '',
2293 :due_date => '',
2288 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
2294 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
2289 }
2295 }
2290 assert_response :success
2296 assert_response :success
2291 assert_template 'new'
2297 assert_template 'new'
2292 end
2298 end
2293
2299
2294 assert_select_error /Due date cannot be blank/i
2300 assert_select_error /Due date cannot be blank/i
2295 assert_select_error /Bar cannot be blank/i
2301 assert_select_error /Bar cannot be blank/i
2296 end
2302 end
2297
2303
2298 def test_create_should_validate_required_list_fields
2304 def test_create_should_validate_required_list_fields
2299 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => false, :possible_values => ['a', 'b'])
2305 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => false, :possible_values => ['a', 'b'])
2300 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => true, :possible_values => ['a', 'b'])
2306 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => true, :possible_values => ['a', 'b'])
2301 WorkflowPermission.delete_all
2307 WorkflowPermission.delete_all
2302 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf1.id.to_s, :rule => 'required')
2308 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf1.id.to_s, :rule => 'required')
2303 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2309 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2304 @request.session[:user_id] = 2
2310 @request.session[:user_id] = 2
2305
2311
2306 assert_no_difference 'Issue.count' do
2312 assert_no_difference 'Issue.count' do
2307 post :create, :project_id => 1, :issue => {
2313 post :create, :project_id => 1, :issue => {
2308 :tracker_id => 2,
2314 :tracker_id => 2,
2309 :status_id => 1,
2315 :status_id => 1,
2310 :subject => 'Test',
2316 :subject => 'Test',
2311 :start_date => '',
2317 :start_date => '',
2312 :due_date => '',
2318 :due_date => '',
2313 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ['']}
2319 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ['']}
2314 }
2320 }
2315 assert_response :success
2321 assert_response :success
2316 assert_template 'new'
2322 assert_template 'new'
2317 end
2323 end
2318
2324
2319 assert_select_error /Foo cannot be blank/i
2325 assert_select_error /Foo cannot be blank/i
2320 assert_select_error /Bar cannot be blank/i
2326 assert_select_error /Bar cannot be blank/i
2321 end
2327 end
2322
2328
2323 def test_create_should_ignore_readonly_fields
2329 def test_create_should_ignore_readonly_fields
2324 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2330 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2325 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2331 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2326 WorkflowPermission.delete_all
2332 WorkflowPermission.delete_all
2327 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
2333 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
2328 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
2334 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
2329 @request.session[:user_id] = 2
2335 @request.session[:user_id] = 2
2330
2336
2331 assert_difference 'Issue.count' do
2337 assert_difference 'Issue.count' do
2332 post :create, :project_id => 1, :issue => {
2338 post :create, :project_id => 1, :issue => {
2333 :tracker_id => 2,
2339 :tracker_id => 2,
2334 :status_id => 1,
2340 :status_id => 1,
2335 :subject => 'Test',
2341 :subject => 'Test',
2336 :start_date => '2012-07-14',
2342 :start_date => '2012-07-14',
2337 :due_date => '2012-07-16',
2343 :due_date => '2012-07-16',
2338 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
2344 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
2339 }
2345 }
2340 assert_response 302
2346 assert_response 302
2341 end
2347 end
2342
2348
2343 issue = Issue.order('id DESC').first
2349 issue = Issue.order('id DESC').first
2344 assert_equal Date.parse('2012-07-14'), issue.start_date
2350 assert_equal Date.parse('2012-07-14'), issue.start_date
2345 assert_nil issue.due_date
2351 assert_nil issue.due_date
2346 assert_equal 'value1', issue.custom_field_value(cf1)
2352 assert_equal 'value1', issue.custom_field_value(cf1)
2347 assert_nil issue.custom_field_value(cf2)
2353 assert_nil issue.custom_field_value(cf2)
2348 end
2354 end
2349
2355
2350 def test_post_create_with_watchers
2356 def test_post_create_with_watchers
2351 @request.session[:user_id] = 2
2357 @request.session[:user_id] = 2
2352 ActionMailer::Base.deliveries.clear
2358 ActionMailer::Base.deliveries.clear
2353
2359
2354 with_settings :notified_events => %w(issue_added) do
2360 with_settings :notified_events => %w(issue_added) do
2355 assert_difference 'Watcher.count', 2 do
2361 assert_difference 'Watcher.count', 2 do
2356 post :create, :project_id => 1,
2362 post :create, :project_id => 1,
2357 :issue => {:tracker_id => 1,
2363 :issue => {:tracker_id => 1,
2358 :subject => 'This is a new issue with watchers',
2364 :subject => 'This is a new issue with watchers',
2359 :description => 'This is the description',
2365 :description => 'This is the description',
2360 :priority_id => 5,
2366 :priority_id => 5,
2361 :watcher_user_ids => ['2', '3']}
2367 :watcher_user_ids => ['2', '3']}
2362 end
2368 end
2363 end
2369 end
2364 issue = Issue.find_by_subject('This is a new issue with watchers')
2370 issue = Issue.find_by_subject('This is a new issue with watchers')
2365 assert_not_nil issue
2371 assert_not_nil issue
2366 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
2372 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
2367
2373
2368 # Watchers added
2374 # Watchers added
2369 assert_equal [2, 3], issue.watcher_user_ids.sort
2375 assert_equal [2, 3], issue.watcher_user_ids.sort
2370 assert issue.watched_by?(User.find(3))
2376 assert issue.watched_by?(User.find(3))
2371 # Watchers notified
2377 # Watchers notified
2372 mail = ActionMailer::Base.deliveries.last
2378 mail = ActionMailer::Base.deliveries.last
2373 assert_not_nil mail
2379 assert_not_nil mail
2374 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
2380 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
2375 end
2381 end
2376
2382
2377 def test_post_create_subissue
2383 def test_post_create_subissue
2378 @request.session[:user_id] = 2
2384 @request.session[:user_id] = 2
2379
2385
2380 assert_difference 'Issue.count' do
2386 assert_difference 'Issue.count' do
2381 post :create, :project_id => 1,
2387 post :create, :project_id => 1,
2382 :issue => {:tracker_id => 1,
2388 :issue => {:tracker_id => 1,
2383 :subject => 'This is a child issue',
2389 :subject => 'This is a child issue',
2384 :parent_issue_id => '2'}
2390 :parent_issue_id => '2'}
2385 assert_response 302
2391 assert_response 302
2386 end
2392 end
2387 issue = Issue.order('id DESC').first
2393 issue = Issue.order('id DESC').first
2388 assert_equal Issue.find(2), issue.parent
2394 assert_equal Issue.find(2), issue.parent
2389 end
2395 end
2390
2396
2391 def test_post_create_subissue_with_sharp_parent_id
2397 def test_post_create_subissue_with_sharp_parent_id
2392 @request.session[:user_id] = 2
2398 @request.session[:user_id] = 2
2393
2399
2394 assert_difference 'Issue.count' do
2400 assert_difference 'Issue.count' do
2395 post :create, :project_id => 1,
2401 post :create, :project_id => 1,
2396 :issue => {:tracker_id => 1,
2402 :issue => {:tracker_id => 1,
2397 :subject => 'This is a child issue',
2403 :subject => 'This is a child issue',
2398 :parent_issue_id => '#2'}
2404 :parent_issue_id => '#2'}
2399 assert_response 302
2405 assert_response 302
2400 end
2406 end
2401 issue = Issue.order('id DESC').first
2407 issue = Issue.order('id DESC').first
2402 assert_equal Issue.find(2), issue.parent
2408 assert_equal Issue.find(2), issue.parent
2403 end
2409 end
2404
2410
2405 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
2411 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
2406 @request.session[:user_id] = 2
2412 @request.session[:user_id] = 2
2407
2413
2408 assert_no_difference 'Issue.count' do
2414 assert_no_difference 'Issue.count' do
2409 post :create, :project_id => 1,
2415 post :create, :project_id => 1,
2410 :issue => {:tracker_id => 1,
2416 :issue => {:tracker_id => 1,
2411 :subject => 'This is a child issue',
2417 :subject => 'This is a child issue',
2412 :parent_issue_id => '4'}
2418 :parent_issue_id => '4'}
2413
2419
2414 assert_response :success
2420 assert_response :success
2415 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2421 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2416 assert_select_error /Parent task is invalid/i
2422 assert_select_error /Parent task is invalid/i
2417 end
2423 end
2418 end
2424 end
2419
2425
2420 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2426 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2421 @request.session[:user_id] = 2
2427 @request.session[:user_id] = 2
2422
2428
2423 assert_no_difference 'Issue.count' do
2429 assert_no_difference 'Issue.count' do
2424 post :create, :project_id => 1,
2430 post :create, :project_id => 1,
2425 :issue => {:tracker_id => 1,
2431 :issue => {:tracker_id => 1,
2426 :subject => 'This is a child issue',
2432 :subject => 'This is a child issue',
2427 :parent_issue_id => '01ABC'}
2433 :parent_issue_id => '01ABC'}
2428
2434
2429 assert_response :success
2435 assert_response :success
2430 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2436 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2431 assert_select_error /Parent task is invalid/i
2437 assert_select_error /Parent task is invalid/i
2432 end
2438 end
2433 end
2439 end
2434
2440
2435 def test_post_create_private
2441 def test_post_create_private
2436 @request.session[:user_id] = 2
2442 @request.session[:user_id] = 2
2437
2443
2438 assert_difference 'Issue.count' do
2444 assert_difference 'Issue.count' do
2439 post :create, :project_id => 1,
2445 post :create, :project_id => 1,
2440 :issue => {:tracker_id => 1,
2446 :issue => {:tracker_id => 1,
2441 :subject => 'This is a private issue',
2447 :subject => 'This is a private issue',
2442 :is_private => '1'}
2448 :is_private => '1'}
2443 end
2449 end
2444 issue = Issue.order('id DESC').first
2450 issue = Issue.order('id DESC').first
2445 assert issue.is_private?
2451 assert issue.is_private?
2446 end
2452 end
2447
2453
2448 def test_post_create_private_with_set_own_issues_private_permission
2454 def test_post_create_private_with_set_own_issues_private_permission
2449 role = Role.find(1)
2455 role = Role.find(1)
2450 role.remove_permission! :set_issues_private
2456 role.remove_permission! :set_issues_private
2451 role.add_permission! :set_own_issues_private
2457 role.add_permission! :set_own_issues_private
2452
2458
2453 @request.session[:user_id] = 2
2459 @request.session[:user_id] = 2
2454
2460
2455 assert_difference 'Issue.count' do
2461 assert_difference 'Issue.count' do
2456 post :create, :project_id => 1,
2462 post :create, :project_id => 1,
2457 :issue => {:tracker_id => 1,
2463 :issue => {:tracker_id => 1,
2458 :subject => 'This is a private issue',
2464 :subject => 'This is a private issue',
2459 :is_private => '1'}
2465 :is_private => '1'}
2460 end
2466 end
2461 issue = Issue.order('id DESC').first
2467 issue = Issue.order('id DESC').first
2462 assert issue.is_private?
2468 assert issue.is_private?
2463 end
2469 end
2464
2470
2465 def test_create_without_project_id
2471 def test_create_without_project_id
2466 @request.session[:user_id] = 2
2472 @request.session[:user_id] = 2
2467
2473
2468 assert_difference 'Issue.count' do
2474 assert_difference 'Issue.count' do
2469 post :create,
2475 post :create,
2470 :issue => {:project_id => 3,
2476 :issue => {:project_id => 3,
2471 :tracker_id => 2,
2477 :tracker_id => 2,
2472 :subject => 'Foo'}
2478 :subject => 'Foo'}
2473 assert_response 302
2479 assert_response 302
2474 end
2480 end
2475 issue = Issue.order('id DESC').first
2481 issue = Issue.order('id DESC').first
2476 assert_equal 3, issue.project_id
2482 assert_equal 3, issue.project_id
2477 assert_equal 2, issue.tracker_id
2483 assert_equal 2, issue.tracker_id
2478 end
2484 end
2479
2485
2480 def test_create_without_project_id_and_continue_should_redirect_without_project_id
2486 def test_create_without_project_id_and_continue_should_redirect_without_project_id
2481 @request.session[:user_id] = 2
2487 @request.session[:user_id] = 2
2482
2488
2483 assert_difference 'Issue.count' do
2489 assert_difference 'Issue.count' do
2484 post :create,
2490 post :create,
2485 :issue => {:project_id => 3,
2491 :issue => {:project_id => 3,
2486 :tracker_id => 2,
2492 :tracker_id => 2,
2487 :subject => 'Foo'},
2493 :subject => 'Foo'},
2488 :continue => '1'
2494 :continue => '1'
2489 assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
2495 assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
2490 end
2496 end
2491 end
2497 end
2492
2498
2493 def test_create_without_project_id_should_be_denied_without_permission
2499 def test_create_without_project_id_should_be_denied_without_permission
2494 Role.non_member.remove_permission! :add_issues
2500 Role.non_member.remove_permission! :add_issues
2495 Role.anonymous.remove_permission! :add_issues
2501 Role.anonymous.remove_permission! :add_issues
2496 @request.session[:user_id] = 2
2502 @request.session[:user_id] = 2
2497
2503
2498 assert_no_difference 'Issue.count' do
2504 assert_no_difference 'Issue.count' do
2499 post :create,
2505 post :create,
2500 :issue => {:project_id => 3,
2506 :issue => {:project_id => 3,
2501 :tracker_id => 2,
2507 :tracker_id => 2,
2502 :subject => 'Foo'}
2508 :subject => 'Foo'}
2503 assert_response 422
2509 assert_response 422
2504 end
2510 end
2505 end
2511 end
2506
2512
2507 def test_create_without_project_id_with_failure
2513 def test_create_without_project_id_with_failure
2508 @request.session[:user_id] = 2
2514 @request.session[:user_id] = 2
2509
2515
2510 post :create,
2516 post :create,
2511 :issue => {:project_id => 3,
2517 :issue => {:project_id => 3,
2512 :tracker_id => 2,
2518 :tracker_id => 2,
2513 :subject => ''}
2519 :subject => ''}
2514 assert_response :success
2520 assert_response :success
2515 assert_nil assigns(:project)
2521 assert_nil assigns(:project)
2516 end
2522 end
2517
2523
2518 def test_post_create_should_send_a_notification
2524 def test_post_create_should_send_a_notification
2519 ActionMailer::Base.deliveries.clear
2525 ActionMailer::Base.deliveries.clear
2520 @request.session[:user_id] = 2
2526 @request.session[:user_id] = 2
2521 with_settings :notified_events => %w(issue_added) do
2527 with_settings :notified_events => %w(issue_added) do
2522 assert_difference 'Issue.count' do
2528 assert_difference 'Issue.count' do
2523 post :create, :project_id => 1,
2529 post :create, :project_id => 1,
2524 :issue => {:tracker_id => 3,
2530 :issue => {:tracker_id => 3,
2525 :subject => 'This is the test_new issue',
2531 :subject => 'This is the test_new issue',
2526 :description => 'This is the description',
2532 :description => 'This is the description',
2527 :priority_id => 5,
2533 :priority_id => 5,
2528 :estimated_hours => '',
2534 :estimated_hours => '',
2529 :custom_field_values => {'2' => 'Value for field 2'}}
2535 :custom_field_values => {'2' => 'Value for field 2'}}
2530 end
2536 end
2531 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2537 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2532
2538
2533 assert_equal 1, ActionMailer::Base.deliveries.size
2539 assert_equal 1, ActionMailer::Base.deliveries.size
2534 end
2540 end
2535 end
2541 end
2536
2542
2537 def test_post_create_should_preserve_fields_values_on_validation_failure
2543 def test_post_create_should_preserve_fields_values_on_validation_failure
2538 @request.session[:user_id] = 2
2544 @request.session[:user_id] = 2
2539 post :create, :project_id => 1,
2545 post :create, :project_id => 1,
2540 :issue => {:tracker_id => 1,
2546 :issue => {:tracker_id => 1,
2541 # empty subject
2547 # empty subject
2542 :subject => '',
2548 :subject => '',
2543 :description => 'This is a description',
2549 :description => 'This is a description',
2544 :priority_id => 6,
2550 :priority_id => 6,
2545 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2551 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2546 assert_response :success
2552 assert_response :success
2547 assert_template 'new'
2553 assert_template 'new'
2548
2554
2549 assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
2555 assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
2550 assert_select 'select[name=?]', 'issue[priority_id]' do
2556 assert_select 'select[name=?]', 'issue[priority_id]' do
2551 assert_select 'option[value="6"][selected=selected]', :text => 'High'
2557 assert_select 'option[value="6"][selected=selected]', :text => 'High'
2552 end
2558 end
2553 # Custom fields
2559 # Custom fields
2554 assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
2560 assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
2555 assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
2561 assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
2556 end
2562 end
2557 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
2563 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
2558 end
2564 end
2559
2565
2560 def test_post_create_with_failure_should_preserve_watchers
2566 def test_post_create_with_failure_should_preserve_watchers
2561 assert !User.find(8).member_of?(Project.find(1))
2567 assert !User.find(8).member_of?(Project.find(1))
2562
2568
2563 @request.session[:user_id] = 2
2569 @request.session[:user_id] = 2
2564 post :create, :project_id => 1,
2570 post :create, :project_id => 1,
2565 :issue => {:tracker_id => 1,
2571 :issue => {:tracker_id => 1,
2566 :watcher_user_ids => ['3', '8']}
2572 :watcher_user_ids => ['3', '8']}
2567 assert_response :success
2573 assert_response :success
2568 assert_template 'new'
2574 assert_template 'new'
2569
2575
2570 assert_select 'input[name=?][value="2"]:not(checked)', 'issue[watcher_user_ids][]'
2576 assert_select 'input[name=?][value="2"]:not(checked)', 'issue[watcher_user_ids][]'
2571 assert_select 'input[name=?][value="3"][checked=checked]', 'issue[watcher_user_ids][]'
2577 assert_select 'input[name=?][value="3"][checked=checked]', 'issue[watcher_user_ids][]'
2572 assert_select 'input[name=?][value="8"][checked=checked]', 'issue[watcher_user_ids][]'
2578 assert_select 'input[name=?][value="8"][checked=checked]', 'issue[watcher_user_ids][]'
2573 end
2579 end
2574
2580
2575 def test_post_create_should_ignore_non_safe_attributes
2581 def test_post_create_should_ignore_non_safe_attributes
2576 @request.session[:user_id] = 2
2582 @request.session[:user_id] = 2
2577 assert_nothing_raised do
2583 assert_nothing_raised do
2578 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2584 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2579 end
2585 end
2580 end
2586 end
2581
2587
2582 def test_post_create_with_attachment
2588 def test_post_create_with_attachment
2583 set_tmp_attachments_directory
2589 set_tmp_attachments_directory
2584 @request.session[:user_id] = 2
2590 @request.session[:user_id] = 2
2585
2591
2586 assert_difference 'Issue.count' do
2592 assert_difference 'Issue.count' do
2587 assert_difference 'Attachment.count' do
2593 assert_difference 'Attachment.count' do
2588 assert_no_difference 'Journal.count' do
2594 assert_no_difference 'Journal.count' do
2589 post :create, :project_id => 1,
2595 post :create, :project_id => 1,
2590 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2596 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2591 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2597 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2592 end
2598 end
2593 end
2599 end
2594 end
2600 end
2595
2601
2596 issue = Issue.order('id DESC').first
2602 issue = Issue.order('id DESC').first
2597 attachment = Attachment.order('id DESC').first
2603 attachment = Attachment.order('id DESC').first
2598
2604
2599 assert_equal issue, attachment.container
2605 assert_equal issue, attachment.container
2600 assert_equal 2, attachment.author_id
2606 assert_equal 2, attachment.author_id
2601 assert_equal 'testfile.txt', attachment.filename
2607 assert_equal 'testfile.txt', attachment.filename
2602 assert_equal 'text/plain', attachment.content_type
2608 assert_equal 'text/plain', attachment.content_type
2603 assert_equal 'test file', attachment.description
2609 assert_equal 'test file', attachment.description
2604 assert_equal 59, attachment.filesize
2610 assert_equal 59, attachment.filesize
2605 assert File.exists?(attachment.diskfile)
2611 assert File.exists?(attachment.diskfile)
2606 assert_equal 59, File.size(attachment.diskfile)
2612 assert_equal 59, File.size(attachment.diskfile)
2607 end
2613 end
2608
2614
2609 def test_post_create_with_attachment_should_notify_with_attachments
2615 def test_post_create_with_attachment_should_notify_with_attachments
2610 ActionMailer::Base.deliveries.clear
2616 ActionMailer::Base.deliveries.clear
2611 set_tmp_attachments_directory
2617 set_tmp_attachments_directory
2612 @request.session[:user_id] = 2
2618 @request.session[:user_id] = 2
2613
2619
2614 with_settings :notified_events => %w(issue_added) do
2620 with_settings :notified_events => %w(issue_added) do
2615 assert_difference 'Issue.count' do
2621 assert_difference 'Issue.count' do
2616 post :create, :project_id => 1,
2622 post :create, :project_id => 1,
2617 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2623 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2618 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2624 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2619 end
2625 end
2620 end
2626 end
2621
2627
2622 assert_not_nil ActionMailer::Base.deliveries.last
2628 assert_not_nil ActionMailer::Base.deliveries.last
2623 assert_select_email do
2629 assert_select_email do
2624 assert_select 'a[href^=?]', 'http://localhost:3000/attachments/download', 'testfile.txt'
2630 assert_select 'a[href^=?]', 'http://localhost:3000/attachments/download', 'testfile.txt'
2625 end
2631 end
2626 end
2632 end
2627
2633
2628 def test_post_create_with_failure_should_save_attachments
2634 def test_post_create_with_failure_should_save_attachments
2629 set_tmp_attachments_directory
2635 set_tmp_attachments_directory
2630 @request.session[:user_id] = 2
2636 @request.session[:user_id] = 2
2631
2637
2632 assert_no_difference 'Issue.count' do
2638 assert_no_difference 'Issue.count' do
2633 assert_difference 'Attachment.count' do
2639 assert_difference 'Attachment.count' do
2634 post :create, :project_id => 1,
2640 post :create, :project_id => 1,
2635 :issue => { :tracker_id => '1', :subject => '' },
2641 :issue => { :tracker_id => '1', :subject => '' },
2636 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2642 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2637 assert_response :success
2643 assert_response :success
2638 assert_template 'new'
2644 assert_template 'new'
2639 end
2645 end
2640 end
2646 end
2641
2647
2642 attachment = Attachment.order('id DESC').first
2648 attachment = Attachment.order('id DESC').first
2643 assert_equal 'testfile.txt', attachment.filename
2649 assert_equal 'testfile.txt', attachment.filename
2644 assert File.exists?(attachment.diskfile)
2650 assert File.exists?(attachment.diskfile)
2645 assert_nil attachment.container
2651 assert_nil attachment.container
2646
2652
2647 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2653 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2648 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2654 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2649 end
2655 end
2650
2656
2651 def test_post_create_with_failure_should_keep_saved_attachments
2657 def test_post_create_with_failure_should_keep_saved_attachments
2652 set_tmp_attachments_directory
2658 set_tmp_attachments_directory
2653 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2659 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2654 @request.session[:user_id] = 2
2660 @request.session[:user_id] = 2
2655
2661
2656 assert_no_difference 'Issue.count' do
2662 assert_no_difference 'Issue.count' do
2657 assert_no_difference 'Attachment.count' do
2663 assert_no_difference 'Attachment.count' do
2658 post :create, :project_id => 1,
2664 post :create, :project_id => 1,
2659 :issue => { :tracker_id => '1', :subject => '' },
2665 :issue => { :tracker_id => '1', :subject => '' },
2660 :attachments => {'p0' => {'token' => attachment.token}}
2666 :attachments => {'p0' => {'token' => attachment.token}}
2661 assert_response :success
2667 assert_response :success
2662 assert_template 'new'
2668 assert_template 'new'
2663 end
2669 end
2664 end
2670 end
2665
2671
2666 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2672 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2667 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2673 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2668 end
2674 end
2669
2675
2670 def test_post_create_should_attach_saved_attachments
2676 def test_post_create_should_attach_saved_attachments
2671 set_tmp_attachments_directory
2677 set_tmp_attachments_directory
2672 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2678 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2673 @request.session[:user_id] = 2
2679 @request.session[:user_id] = 2
2674
2680
2675 assert_difference 'Issue.count' do
2681 assert_difference 'Issue.count' do
2676 assert_no_difference 'Attachment.count' do
2682 assert_no_difference 'Attachment.count' do
2677 post :create, :project_id => 1,
2683 post :create, :project_id => 1,
2678 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2684 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2679 :attachments => {'p0' => {'token' => attachment.token}}
2685 :attachments => {'p0' => {'token' => attachment.token}}
2680 assert_response 302
2686 assert_response 302
2681 end
2687 end
2682 end
2688 end
2683
2689
2684 issue = Issue.order('id DESC').first
2690 issue = Issue.order('id DESC').first
2685 assert_equal 1, issue.attachments.count
2691 assert_equal 1, issue.attachments.count
2686
2692
2687 attachment.reload
2693 attachment.reload
2688 assert_equal issue, attachment.container
2694 assert_equal issue, attachment.container
2689 end
2695 end
2690
2696
2691 def setup_without_workflow_privilege
2697 def setup_without_workflow_privilege
2692 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2698 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2693 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2699 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2694 end
2700 end
2695 private :setup_without_workflow_privilege
2701 private :setup_without_workflow_privilege
2696
2702
2697 test "without workflow privilege #new should propose default status only" do
2703 test "without workflow privilege #new should propose default status only" do
2698 setup_without_workflow_privilege
2704 setup_without_workflow_privilege
2699 get :new, :project_id => 1
2705 get :new, :project_id => 1
2700 assert_response :success
2706 assert_response :success
2701 assert_template 'new'
2707 assert_template 'new'
2702
2708
2703 issue = assigns(:issue)
2709 issue = assigns(:issue)
2704 assert_not_nil issue.default_status
2710 assert_not_nil issue.default_status
2705
2711
2706 assert_select 'select[name=?]', 'issue[status_id]' do
2712 assert_select 'select[name=?]', 'issue[status_id]' do
2707 assert_select 'option', 1
2713 assert_select 'option', 1
2708 assert_select 'option[value=?]', issue.default_status.id.to_s
2714 assert_select 'option[value=?]', issue.default_status.id.to_s
2709 end
2715 end
2710 end
2716 end
2711
2717
2712 test "without workflow privilege #create should accept default status" do
2718 test "without workflow privilege #create should accept default status" do
2713 setup_without_workflow_privilege
2719 setup_without_workflow_privilege
2714 assert_difference 'Issue.count' do
2720 assert_difference 'Issue.count' do
2715 post :create, :project_id => 1,
2721 post :create, :project_id => 1,
2716 :issue => {:tracker_id => 1,
2722 :issue => {:tracker_id => 1,
2717 :subject => 'This is an issue',
2723 :subject => 'This is an issue',
2718 :status_id => 1}
2724 :status_id => 1}
2719 end
2725 end
2720 issue = Issue.order('id').last
2726 issue = Issue.order('id').last
2721 assert_not_nil issue.default_status
2727 assert_not_nil issue.default_status
2722 assert_equal issue.default_status, issue.status
2728 assert_equal issue.default_status, issue.status
2723 end
2729 end
2724
2730
2725 test "without workflow privilege #create should ignore unauthorized status" do
2731 test "without workflow privilege #create should ignore unauthorized status" do
2726 setup_without_workflow_privilege
2732 setup_without_workflow_privilege
2727 assert_difference 'Issue.count' do
2733 assert_difference 'Issue.count' do
2728 post :create, :project_id => 1,
2734 post :create, :project_id => 1,
2729 :issue => {:tracker_id => 1,
2735 :issue => {:tracker_id => 1,
2730 :subject => 'This is an issue',
2736 :subject => 'This is an issue',
2731 :status_id => 3}
2737 :status_id => 3}
2732 end
2738 end
2733 issue = Issue.order('id').last
2739 issue = Issue.order('id').last
2734 assert_not_nil issue.default_status
2740 assert_not_nil issue.default_status
2735 assert_equal issue.default_status, issue.status
2741 assert_equal issue.default_status, issue.status
2736 end
2742 end
2737
2743
2738 test "without workflow privilege #update should ignore status change" do
2744 test "without workflow privilege #update should ignore status change" do
2739 setup_without_workflow_privilege
2745 setup_without_workflow_privilege
2740 assert_difference 'Journal.count' do
2746 assert_difference 'Journal.count' do
2741 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2747 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2742 end
2748 end
2743 assert_equal 1, Issue.find(1).status_id
2749 assert_equal 1, Issue.find(1).status_id
2744 end
2750 end
2745
2751
2746 test "without workflow privilege #update ignore attributes changes" do
2752 test "without workflow privilege #update ignore attributes changes" do
2747 setup_without_workflow_privilege
2753 setup_without_workflow_privilege
2748 assert_difference 'Journal.count' do
2754 assert_difference 'Journal.count' do
2749 put :update, :id => 1,
2755 put :update, :id => 1,
2750 :issue => {:subject => 'changed', :assigned_to_id => 2,
2756 :issue => {:subject => 'changed', :assigned_to_id => 2,
2751 :notes => 'just trying'}
2757 :notes => 'just trying'}
2752 end
2758 end
2753 issue = Issue.find(1)
2759 issue = Issue.find(1)
2754 assert_equal "Cannot print recipes", issue.subject
2760 assert_equal "Cannot print recipes", issue.subject
2755 assert_nil issue.assigned_to
2761 assert_nil issue.assigned_to
2756 end
2762 end
2757
2763
2758 def setup_with_workflow_privilege
2764 def setup_with_workflow_privilege
2759 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2765 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2760 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2766 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2761 :old_status_id => 1, :new_status_id => 3)
2767 :old_status_id => 1, :new_status_id => 3)
2762 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2768 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2763 :old_status_id => 1, :new_status_id => 4)
2769 :old_status_id => 1, :new_status_id => 4)
2764 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2770 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2765 end
2771 end
2766 private :setup_with_workflow_privilege
2772 private :setup_with_workflow_privilege
2767
2773
2768 def setup_with_workflow_privilege_and_edit_issues_permission
2774 def setup_with_workflow_privilege_and_edit_issues_permission
2769 setup_with_workflow_privilege
2775 setup_with_workflow_privilege
2770 Role.anonymous.add_permission! :add_issues, :edit_issues
2776 Role.anonymous.add_permission! :add_issues, :edit_issues
2771 end
2777 end
2772 private :setup_with_workflow_privilege_and_edit_issues_permission
2778 private :setup_with_workflow_privilege_and_edit_issues_permission
2773
2779
2774 test "with workflow privilege and :edit_issues permission should accept authorized status" do
2780 test "with workflow privilege and :edit_issues permission should accept authorized status" do
2775 setup_with_workflow_privilege_and_edit_issues_permission
2781 setup_with_workflow_privilege_and_edit_issues_permission
2776 assert_difference 'Journal.count' do
2782 assert_difference 'Journal.count' do
2777 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2783 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2778 end
2784 end
2779 assert_equal 3, Issue.find(1).status_id
2785 assert_equal 3, Issue.find(1).status_id
2780 end
2786 end
2781
2787
2782 test "with workflow privilege and :edit_issues permission should ignore unauthorized status" do
2788 test "with workflow privilege and :edit_issues permission should ignore unauthorized status" do
2783 setup_with_workflow_privilege_and_edit_issues_permission
2789 setup_with_workflow_privilege_and_edit_issues_permission
2784 assert_difference 'Journal.count' do
2790 assert_difference 'Journal.count' do
2785 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2791 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2786 end
2792 end
2787 assert_equal 1, Issue.find(1).status_id
2793 assert_equal 1, Issue.find(1).status_id
2788 end
2794 end
2789
2795
2790 test "with workflow privilege and :edit_issues permission should accept authorized attributes changes" do
2796 test "with workflow privilege and :edit_issues permission should accept authorized attributes changes" do
2791 setup_with_workflow_privilege_and_edit_issues_permission
2797 setup_with_workflow_privilege_and_edit_issues_permission
2792 assert_difference 'Journal.count' do
2798 assert_difference 'Journal.count' do
2793 put :update, :id => 1,
2799 put :update, :id => 1,
2794 :issue => {:subject => 'changed', :assigned_to_id => 2,
2800 :issue => {:subject => 'changed', :assigned_to_id => 2,
2795 :notes => 'just trying'}
2801 :notes => 'just trying'}
2796 end
2802 end
2797 issue = Issue.find(1)
2803 issue = Issue.find(1)
2798 assert_equal "changed", issue.subject
2804 assert_equal "changed", issue.subject
2799 assert_equal 2, issue.assigned_to_id
2805 assert_equal 2, issue.assigned_to_id
2800 end
2806 end
2801
2807
2802 def test_new_as_copy
2808 def test_new_as_copy
2803 @request.session[:user_id] = 2
2809 @request.session[:user_id] = 2
2804 get :new, :project_id => 1, :copy_from => 1
2810 get :new, :project_id => 1, :copy_from => 1
2805
2811
2806 assert_response :success
2812 assert_response :success
2807 assert_template 'new'
2813 assert_template 'new'
2808
2814
2809 assert_not_nil assigns(:issue)
2815 assert_not_nil assigns(:issue)
2810 orig = Issue.find(1)
2816 orig = Issue.find(1)
2811 assert_equal 1, assigns(:issue).project_id
2817 assert_equal 1, assigns(:issue).project_id
2812 assert_equal orig.subject, assigns(:issue).subject
2818 assert_equal orig.subject, assigns(:issue).subject
2813 assert assigns(:issue).copy?
2819 assert assigns(:issue).copy?
2814
2820
2815 assert_select 'form[id=issue-form][action="/projects/ecookbook/issues"]' do
2821 assert_select 'form[id=issue-form][action="/projects/ecookbook/issues"]' do
2816 assert_select 'select[name=?]', 'issue[project_id]' do
2822 assert_select 'select[name=?]', 'issue[project_id]' do
2817 assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
2823 assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
2818 assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
2824 assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
2819 end
2825 end
2820 assert_select 'input[name=copy_from][value="1"]'
2826 assert_select 'input[name=copy_from][value="1"]'
2821 end
2827 end
2822 end
2828 end
2823
2829
2824 def test_new_as_copy_without_add_issues_permission_should_not_propose_current_project_as_target
2830 def test_new_as_copy_without_add_issues_permission_should_not_propose_current_project_as_target
2825 user = setup_user_with_copy_but_not_add_permission
2831 user = setup_user_with_copy_but_not_add_permission
2826
2832
2827 @request.session[:user_id] = user.id
2833 @request.session[:user_id] = user.id
2828 get :new, :project_id => 1, :copy_from => 1
2834 get :new, :project_id => 1, :copy_from => 1
2829
2835
2830 assert_response :success
2836 assert_response :success
2831 assert_template 'new'
2837 assert_template 'new'
2832 assert_select 'select[name=?]', 'issue[project_id]' do
2838 assert_select 'select[name=?]', 'issue[project_id]' do
2833 assert_select 'option[value="1"]', 0
2839 assert_select 'option[value="1"]', 0
2834 assert_select 'option[value="2"]', :text => 'OnlineStore'
2840 assert_select 'option[value="2"]', :text => 'OnlineStore'
2835 end
2841 end
2836 end
2842 end
2837
2843
2838 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2844 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2839 @request.session[:user_id] = 2
2845 @request.session[:user_id] = 2
2840 issue = Issue.find(3)
2846 issue = Issue.find(3)
2841 assert issue.attachments.count > 0
2847 assert issue.attachments.count > 0
2842 get :new, :project_id => 1, :copy_from => 3
2848 get :new, :project_id => 1, :copy_from => 3
2843
2849
2844 assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value="1"]'
2850 assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value="1"]'
2845 end
2851 end
2846
2852
2847 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2853 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2848 @request.session[:user_id] = 2
2854 @request.session[:user_id] = 2
2849 issue = Issue.find(3)
2855 issue = Issue.find(3)
2850 issue.attachments.delete_all
2856 issue.attachments.delete_all
2851 get :new, :project_id => 1, :copy_from => 3
2857 get :new, :project_id => 1, :copy_from => 3
2852
2858
2853 assert_select 'input[name=copy_attachments]', 0
2859 assert_select 'input[name=copy_attachments]', 0
2854 end
2860 end
2855
2861
2856 def test_new_as_copy_should_preserve_parent_id
2862 def test_new_as_copy_should_preserve_parent_id
2857 @request.session[:user_id] = 2
2863 @request.session[:user_id] = 2
2858 issue = Issue.generate!(:parent_issue_id => 2)
2864 issue = Issue.generate!(:parent_issue_id => 2)
2859 get :new, :project_id => 1, :copy_from => issue.id
2865 get :new, :project_id => 1, :copy_from => issue.id
2860
2866
2861 assert_select 'input[name=?][value="2"]', 'issue[parent_issue_id]'
2867 assert_select 'input[name=?][value="2"]', 'issue[parent_issue_id]'
2862 end
2868 end
2863
2869
2864 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2870 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2865 @request.session[:user_id] = 2
2871 @request.session[:user_id] = 2
2866 issue = Issue.generate_with_descendants!
2872 issue = Issue.generate_with_descendants!
2867 get :new, :project_id => 1, :copy_from => issue.id
2873 get :new, :project_id => 1, :copy_from => issue.id
2868
2874
2869 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value="1"]'
2875 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value="1"]'
2870 end
2876 end
2871
2877
2872 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2878 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2873 @request.session[:user_id] = 2
2879 @request.session[:user_id] = 2
2874 get :new, :project_id => 1, :copy_from => 99999
2880 get :new, :project_id => 1, :copy_from => 99999
2875 assert_response 404
2881 assert_response 404
2876 end
2882 end
2877
2883
2878 def test_create_as_copy_on_different_project
2884 def test_create_as_copy_on_different_project
2879 @request.session[:user_id] = 2
2885 @request.session[:user_id] = 2
2880 assert_difference 'Issue.count' do
2886 assert_difference 'Issue.count' do
2881 post :create, :project_id => 1, :copy_from => 1,
2887 post :create, :project_id => 1, :copy_from => 1,
2882 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2888 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2883
2889
2884 assert_not_nil assigns(:issue)
2890 assert_not_nil assigns(:issue)
2885 assert assigns(:issue).copy?
2891 assert assigns(:issue).copy?
2886 end
2892 end
2887 issue = Issue.order('id DESC').first
2893 issue = Issue.order('id DESC').first
2888 assert_redirected_to "/issues/#{issue.id}"
2894 assert_redirected_to "/issues/#{issue.id}"
2889
2895
2890 assert_equal 2, issue.project_id
2896 assert_equal 2, issue.project_id
2891 assert_equal 3, issue.tracker_id
2897 assert_equal 3, issue.tracker_id
2892 assert_equal 'Copy', issue.subject
2898 assert_equal 'Copy', issue.subject
2893 end
2899 end
2894
2900
2895 def test_create_as_copy_should_allow_status_to_be_set_to_default
2901 def test_create_as_copy_should_allow_status_to_be_set_to_default
2896 copied = Issue.generate! :status_id => 2
2902 copied = Issue.generate! :status_id => 2
2897 assert_equal 2, copied.reload.status_id
2903 assert_equal 2, copied.reload.status_id
2898
2904
2899 @request.session[:user_id] = 2
2905 @request.session[:user_id] = 2
2900 assert_difference 'Issue.count' do
2906 assert_difference 'Issue.count' do
2901 post :create, :project_id => 1, :copy_from => copied.id,
2907 post :create, :project_id => 1, :copy_from => copied.id,
2902 :issue => {:project_id => '1', :tracker_id => '1', :status_id => '1'},
2908 :issue => {:project_id => '1', :tracker_id => '1', :status_id => '1'},
2903 :was_default_status => '1'
2909 :was_default_status => '1'
2904 end
2910 end
2905 issue = Issue.order('id DESC').first
2911 issue = Issue.order('id DESC').first
2906 assert_equal 1, issue.status_id
2912 assert_equal 1, issue.status_id
2907 end
2913 end
2908
2914
2909 def test_create_as_copy_should_copy_attachments
2915 def test_create_as_copy_should_copy_attachments
2910 @request.session[:user_id] = 2
2916 @request.session[:user_id] = 2
2911 issue = Issue.find(3)
2917 issue = Issue.find(3)
2912 count = issue.attachments.count
2918 count = issue.attachments.count
2913 assert count > 0
2919 assert count > 0
2914 assert_difference 'Issue.count' do
2920 assert_difference 'Issue.count' do
2915 assert_difference 'Attachment.count', count do
2921 assert_difference 'Attachment.count', count do
2916 post :create, :project_id => 1, :copy_from => 3,
2922 post :create, :project_id => 1, :copy_from => 3,
2917 :issue => {:project_id => '1', :tracker_id => '3',
2923 :issue => {:project_id => '1', :tracker_id => '3',
2918 :status_id => '1', :subject => 'Copy with attachments'},
2924 :status_id => '1', :subject => 'Copy with attachments'},
2919 :copy_attachments => '1'
2925 :copy_attachments => '1'
2920 end
2926 end
2921 end
2927 end
2922 copy = Issue.order('id DESC').first
2928 copy = Issue.order('id DESC').first
2923 assert_equal count, copy.attachments.count
2929 assert_equal count, copy.attachments.count
2924 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2930 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2925 end
2931 end
2926
2932
2927 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2933 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2928 @request.session[:user_id] = 2
2934 @request.session[:user_id] = 2
2929 issue = Issue.find(3)
2935 issue = Issue.find(3)
2930 count = issue.attachments.count
2936 count = issue.attachments.count
2931 assert count > 0
2937 assert count > 0
2932 assert_difference 'Issue.count' do
2938 assert_difference 'Issue.count' do
2933 assert_no_difference 'Attachment.count' do
2939 assert_no_difference 'Attachment.count' do
2934 post :create, :project_id => 1, :copy_from => 3,
2940 post :create, :project_id => 1, :copy_from => 3,
2935 :issue => {:project_id => '1', :tracker_id => '3',
2941 :issue => {:project_id => '1', :tracker_id => '3',
2936 :status_id => '1', :subject => 'Copy with attachments'}
2942 :status_id => '1', :subject => 'Copy with attachments'}
2937 end
2943 end
2938 end
2944 end
2939 copy = Issue.order('id DESC').first
2945 copy = Issue.order('id DESC').first
2940 assert_equal 0, copy.attachments.count
2946 assert_equal 0, copy.attachments.count
2941 end
2947 end
2942
2948
2943 def test_create_as_copy_with_attachments_should_also_add_new_files
2949 def test_create_as_copy_with_attachments_should_also_add_new_files
2944 @request.session[:user_id] = 2
2950 @request.session[:user_id] = 2
2945 issue = Issue.find(3)
2951 issue = Issue.find(3)
2946 count = issue.attachments.count
2952 count = issue.attachments.count
2947 assert count > 0
2953 assert count > 0
2948 assert_difference 'Issue.count' do
2954 assert_difference 'Issue.count' do
2949 assert_difference 'Attachment.count', count + 1 do
2955 assert_difference 'Attachment.count', count + 1 do
2950 post :create, :project_id => 1, :copy_from => 3,
2956 post :create, :project_id => 1, :copy_from => 3,
2951 :issue => {:project_id => '1', :tracker_id => '3',
2957 :issue => {:project_id => '1', :tracker_id => '3',
2952 :status_id => '1', :subject => 'Copy with attachments'},
2958 :status_id => '1', :subject => 'Copy with attachments'},
2953 :copy_attachments => '1',
2959 :copy_attachments => '1',
2954 :attachments => {'1' =>
2960 :attachments => {'1' =>
2955 {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
2961 {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
2956 'description' => 'test file'}}
2962 'description' => 'test file'}}
2957 end
2963 end
2958 end
2964 end
2959 copy = Issue.order('id DESC').first
2965 copy = Issue.order('id DESC').first
2960 assert_equal count + 1, copy.attachments.count
2966 assert_equal count + 1, copy.attachments.count
2961 end
2967 end
2962
2968
2963 def test_create_as_copy_should_add_relation_with_copied_issue
2969 def test_create_as_copy_should_add_relation_with_copied_issue
2964 @request.session[:user_id] = 2
2970 @request.session[:user_id] = 2
2965 assert_difference 'Issue.count' do
2971 assert_difference 'Issue.count' do
2966 assert_difference 'IssueRelation.count' do
2972 assert_difference 'IssueRelation.count' do
2967 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2973 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2968 :issue => {:project_id => '1', :tracker_id => '3',
2974 :issue => {:project_id => '1', :tracker_id => '3',
2969 :status_id => '1', :subject => 'Copy'}
2975 :status_id => '1', :subject => 'Copy'}
2970 end
2976 end
2971 end
2977 end
2972 copy = Issue.order('id DESC').first
2978 copy = Issue.order('id DESC').first
2973 assert_equal 1, copy.relations.size
2979 assert_equal 1, copy.relations.size
2974 end
2980 end
2975
2981
2976 def test_create_as_copy_should_allow_not_to_add_relation_with_copied_issue
2982 def test_create_as_copy_should_allow_not_to_add_relation_with_copied_issue
2977 @request.session[:user_id] = 2
2983 @request.session[:user_id] = 2
2978 assert_difference 'Issue.count' do
2984 assert_difference 'Issue.count' do
2979 assert_no_difference 'IssueRelation.count' do
2985 assert_no_difference 'IssueRelation.count' do
2980 post :create, :project_id => 1, :copy_from => 1,
2986 post :create, :project_id => 1, :copy_from => 1,
2981 :issue => {:subject => 'Copy'}
2987 :issue => {:subject => 'Copy'}
2982 end
2988 end
2983 end
2989 end
2984 end
2990 end
2985
2991
2986 def test_create_as_copy_should_always_add_relation_with_copied_issue_by_setting
2992 def test_create_as_copy_should_always_add_relation_with_copied_issue_by_setting
2987 with_settings :link_copied_issue => 'yes' do
2993 with_settings :link_copied_issue => 'yes' do
2988 @request.session[:user_id] = 2
2994 @request.session[:user_id] = 2
2989 assert_difference 'Issue.count' do
2995 assert_difference 'Issue.count' do
2990 assert_difference 'IssueRelation.count' do
2996 assert_difference 'IssueRelation.count' do
2991 post :create, :project_id => 1, :copy_from => 1,
2997 post :create, :project_id => 1, :copy_from => 1,
2992 :issue => {:subject => 'Copy'}
2998 :issue => {:subject => 'Copy'}
2993 end
2999 end
2994 end
3000 end
2995 end
3001 end
2996 end
3002 end
2997
3003
2998 def test_create_as_copy_should_never_add_relation_with_copied_issue_by_setting
3004 def test_create_as_copy_should_never_add_relation_with_copied_issue_by_setting
2999 with_settings :link_copied_issue => 'no' do
3005 with_settings :link_copied_issue => 'no' do
3000 @request.session[:user_id] = 2
3006 @request.session[:user_id] = 2
3001 assert_difference 'Issue.count' do
3007 assert_difference 'Issue.count' do
3002 assert_no_difference 'IssueRelation.count' do
3008 assert_no_difference 'IssueRelation.count' do
3003 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
3009 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
3004 :issue => {:subject => 'Copy'}
3010 :issue => {:subject => 'Copy'}
3005 end
3011 end
3006 end
3012 end
3007 end
3013 end
3008 end
3014 end
3009
3015
3010 def test_create_as_copy_should_copy_subtasks
3016 def test_create_as_copy_should_copy_subtasks
3011 @request.session[:user_id] = 2
3017 @request.session[:user_id] = 2
3012 issue = Issue.generate_with_descendants!
3018 issue = Issue.generate_with_descendants!
3013 count = issue.descendants.count
3019 count = issue.descendants.count
3014 assert_difference 'Issue.count', count + 1 do
3020 assert_difference 'Issue.count', count + 1 do
3015 post :create, :project_id => 1, :copy_from => issue.id,
3021 post :create, :project_id => 1, :copy_from => issue.id,
3016 :issue => {:project_id => '1', :tracker_id => '3',
3022 :issue => {:project_id => '1', :tracker_id => '3',
3017 :status_id => '1', :subject => 'Copy with subtasks'},
3023 :status_id => '1', :subject => 'Copy with subtasks'},
3018 :copy_subtasks => '1'
3024 :copy_subtasks => '1'
3019 end
3025 end
3020 copy = Issue.where(:parent_id => nil).order('id DESC').first
3026 copy = Issue.where(:parent_id => nil).order('id DESC').first
3021 assert_equal count, copy.descendants.count
3027 assert_equal count, copy.descendants.count
3022 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
3028 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
3023 end
3029 end
3024
3030
3025 def test_create_as_copy_to_a_different_project_should_copy_subtask_custom_fields
3031 def test_create_as_copy_to_a_different_project_should_copy_subtask_custom_fields
3026 issue = Issue.generate! {|i| i.custom_field_values = {'2' => 'Foo'}}
3032 issue = Issue.generate! {|i| i.custom_field_values = {'2' => 'Foo'}}
3027 child = Issue.generate!(:parent_issue_id => issue.id) {|i| i.custom_field_values = {'2' => 'Bar'}}
3033 child = Issue.generate!(:parent_issue_id => issue.id) {|i| i.custom_field_values = {'2' => 'Bar'}}
3028 @request.session[:user_id] = 1
3034 @request.session[:user_id] = 1
3029
3035
3030 assert_difference 'Issue.count', 2 do
3036 assert_difference 'Issue.count', 2 do
3031 post :create, :project_id => 'ecookbook', :copy_from => issue.id,
3037 post :create, :project_id => 'ecookbook', :copy_from => issue.id,
3032 :issue => {:project_id => '2', :tracker_id => 1, :status_id => '1',
3038 :issue => {:project_id => '2', :tracker_id => 1, :status_id => '1',
3033 :subject => 'Copy with subtasks', :custom_field_values => {'2' => 'Foo'}},
3039 :subject => 'Copy with subtasks', :custom_field_values => {'2' => 'Foo'}},
3034 :copy_subtasks => '1'
3040 :copy_subtasks => '1'
3035 end
3041 end
3036
3042
3037 child_copy, issue_copy = Issue.order(:id => :desc).limit(2).to_a
3043 child_copy, issue_copy = Issue.order(:id => :desc).limit(2).to_a
3038 assert_equal 2, issue_copy.project_id
3044 assert_equal 2, issue_copy.project_id
3039 assert_equal 'Foo', issue_copy.custom_field_value(2)
3045 assert_equal 'Foo', issue_copy.custom_field_value(2)
3040 assert_equal 'Bar', child_copy.custom_field_value(2)
3046 assert_equal 'Bar', child_copy.custom_field_value(2)
3041 end
3047 end
3042
3048
3043 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
3049 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
3044 @request.session[:user_id] = 2
3050 @request.session[:user_id] = 2
3045 issue = Issue.generate_with_descendants!
3051 issue = Issue.generate_with_descendants!
3046 assert_difference 'Issue.count', 1 do
3052 assert_difference 'Issue.count', 1 do
3047 post :create, :project_id => 1, :copy_from => 3,
3053 post :create, :project_id => 1, :copy_from => 3,
3048 :issue => {:project_id => '1', :tracker_id => '3',
3054 :issue => {:project_id => '1', :tracker_id => '3',
3049 :status_id => '1', :subject => 'Copy with subtasks'}
3055 :status_id => '1', :subject => 'Copy with subtasks'}
3050 end
3056 end
3051 copy = Issue.where(:parent_id => nil).order('id DESC').first
3057 copy = Issue.where(:parent_id => nil).order('id DESC').first
3052 assert_equal 0, copy.descendants.count
3058 assert_equal 0, copy.descendants.count
3053 end
3059 end
3054
3060
3055 def test_create_as_copy_with_failure
3061 def test_create_as_copy_with_failure
3056 @request.session[:user_id] = 2
3062 @request.session[:user_id] = 2
3057 post :create, :project_id => 1, :copy_from => 1,
3063 post :create, :project_id => 1, :copy_from => 1,
3058 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
3064 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
3059
3065
3060 assert_response :success
3066 assert_response :success
3061 assert_template 'new'
3067 assert_template 'new'
3062
3068
3063 assert_not_nil assigns(:issue)
3069 assert_not_nil assigns(:issue)
3064 assert assigns(:issue).copy?
3070 assert assigns(:issue).copy?
3065
3071
3066 assert_select 'form#issue-form[action="/projects/ecookbook/issues"]' do
3072 assert_select 'form#issue-form[action="/projects/ecookbook/issues"]' do
3067 assert_select 'select[name=?]', 'issue[project_id]' do
3073 assert_select 'select[name=?]', 'issue[project_id]' do
3068 assert_select 'option[value="1"]:not([selected])', :text => 'eCookbook'
3074 assert_select 'option[value="1"]:not([selected])', :text => 'eCookbook'
3069 assert_select 'option[value="2"][selected=selected]', :text => 'OnlineStore'
3075 assert_select 'option[value="2"][selected=selected]', :text => 'OnlineStore'
3070 end
3076 end
3071 assert_select 'input[name=copy_from][value="1"]'
3077 assert_select 'input[name=copy_from][value="1"]'
3072 end
3078 end
3073 end
3079 end
3074
3080
3075 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
3081 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
3076 @request.session[:user_id] = 2
3082 @request.session[:user_id] = 2
3077 assert !User.find(2).member_of?(Project.find(4))
3083 assert !User.find(2).member_of?(Project.find(4))
3078
3084
3079 assert_difference 'Issue.count' do
3085 assert_difference 'Issue.count' do
3080 post :create, :project_id => 1, :copy_from => 1,
3086 post :create, :project_id => 1, :copy_from => 1,
3081 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
3087 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
3082 end
3088 end
3083 issue = Issue.order('id DESC').first
3089 issue = Issue.order('id DESC').first
3084 assert_equal 1, issue.project_id
3090 assert_equal 1, issue.project_id
3085 end
3091 end
3086
3092
3087 def test_get_edit
3093 def test_get_edit
3088 @request.session[:user_id] = 2
3094 @request.session[:user_id] = 2
3089 get :edit, :id => 1
3095 get :edit, :id => 1
3090 assert_response :success
3096 assert_response :success
3091 assert_template 'edit'
3097 assert_template 'edit'
3092 assert_not_nil assigns(:issue)
3098 assert_not_nil assigns(:issue)
3093 assert_equal Issue.find(1), assigns(:issue)
3099 assert_equal Issue.find(1), assigns(:issue)
3094
3100
3095 # Be sure we don't display inactive IssuePriorities
3101 # Be sure we don't display inactive IssuePriorities
3096 assert ! IssuePriority.find(15).active?
3102 assert ! IssuePriority.find(15).active?
3097 assert_select 'select[name=?]', 'issue[priority_id]' do
3103 assert_select 'select[name=?]', 'issue[priority_id]' do
3098 assert_select 'option[value="15"]', 0
3104 assert_select 'option[value="15"]', 0
3099 end
3105 end
3100 end
3106 end
3101
3107
3102 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
3108 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
3103 @request.session[:user_id] = 2
3109 @request.session[:user_id] = 2
3104 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
3110 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
3105
3111
3106 get :edit, :id => 1
3112 get :edit, :id => 1
3107 assert_select 'input[name=?]', 'time_entry[hours]'
3113 assert_select 'input[name=?]', 'time_entry[hours]'
3108 end
3114 end
3109
3115
3110 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
3116 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
3111 @request.session[:user_id] = 2
3117 @request.session[:user_id] = 2
3112 Role.find_by_name('Manager').remove_permission! :log_time
3118 Role.find_by_name('Manager').remove_permission! :log_time
3113
3119
3114 get :edit, :id => 1
3120 get :edit, :id => 1
3115 assert_select 'input[name=?]', 'time_entry[hours]', 0
3121 assert_select 'input[name=?]', 'time_entry[hours]', 0
3116 end
3122 end
3117
3123
3118 def test_get_edit_with_params
3124 def test_get_edit_with_params
3119 @request.session[:user_id] = 2
3125 @request.session[:user_id] = 2
3120 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
3126 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
3121 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
3127 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
3122 assert_response :success
3128 assert_response :success
3123 assert_template 'edit'
3129 assert_template 'edit'
3124
3130
3125 issue = assigns(:issue)
3131 issue = assigns(:issue)
3126 assert_not_nil issue
3132 assert_not_nil issue
3127
3133
3128 assert_equal 5, issue.status_id
3134 assert_equal 5, issue.status_id
3129 assert_select 'select[name=?]', 'issue[status_id]' do
3135 assert_select 'select[name=?]', 'issue[status_id]' do
3130 assert_select 'option[value="5"][selected=selected]', :text => 'Closed'
3136 assert_select 'option[value="5"][selected=selected]', :text => 'Closed'
3131 end
3137 end
3132
3138
3133 assert_equal 7, issue.priority_id
3139 assert_equal 7, issue.priority_id
3134 assert_select 'select[name=?]', 'issue[priority_id]' do
3140 assert_select 'select[name=?]', 'issue[priority_id]' do
3135 assert_select 'option[value="7"][selected=selected]', :text => 'Urgent'
3141 assert_select 'option[value="7"][selected=selected]', :text => 'Urgent'
3136 end
3142 end
3137
3143
3138 assert_select 'input[name=?][value="2.5"]', 'time_entry[hours]'
3144 assert_select 'input[name=?][value="2.5"]', 'time_entry[hours]'
3139 assert_select 'select[name=?]', 'time_entry[activity_id]' do
3145 assert_select 'select[name=?]', 'time_entry[activity_id]' do
3140 assert_select 'option[value="10"][selected=selected]', :text => 'Development'
3146 assert_select 'option[value="10"][selected=selected]', :text => 'Development'
3141 end
3147 end
3142 assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
3148 assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
3143 end
3149 end
3144
3150
3145 def test_get_edit_with_multi_custom_field
3151 def test_get_edit_with_multi_custom_field
3146 field = CustomField.find(1)
3152 field = CustomField.find(1)
3147 field.update_attribute :multiple, true
3153 field.update_attribute :multiple, true
3148 issue = Issue.find(1)
3154 issue = Issue.find(1)
3149 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3155 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3150 issue.save!
3156 issue.save!
3151
3157
3152 @request.session[:user_id] = 2
3158 @request.session[:user_id] = 2
3153 get :edit, :id => 1
3159 get :edit, :id => 1
3154 assert_response :success
3160 assert_response :success
3155 assert_template 'edit'
3161 assert_template 'edit'
3156
3162
3157 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
3163 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
3158 assert_select 'option', 3
3164 assert_select 'option', 3
3159 assert_select 'option[value=MySQL][selected=selected]'
3165 assert_select 'option[value=MySQL][selected=selected]'
3160 assert_select 'option[value=Oracle][selected=selected]'
3166 assert_select 'option[value=Oracle][selected=selected]'
3161 assert_select 'option[value=PostgreSQL]:not([selected])'
3167 assert_select 'option[value=PostgreSQL]:not([selected])'
3162 end
3168 end
3163 end
3169 end
3164
3170
3165 def test_update_form_for_existing_issue
3171 def test_update_form_for_existing_issue
3166 @request.session[:user_id] = 2
3172 @request.session[:user_id] = 2
3167 xhr :patch, :edit, :id => 1,
3173 xhr :patch, :edit, :id => 1,
3168 :issue => {:tracker_id => 2,
3174 :issue => {:tracker_id => 2,
3169 :subject => 'This is the test_new issue',
3175 :subject => 'This is the test_new issue',
3170 :description => 'This is the description',
3176 :description => 'This is the description',
3171 :priority_id => 5}
3177 :priority_id => 5}
3172 assert_response :success
3178 assert_response :success
3173 assert_equal 'text/javascript', response.content_type
3179 assert_equal 'text/javascript', response.content_type
3174 assert_template 'edit'
3180 assert_template 'edit'
3175 assert_template :partial => '_form'
3181 assert_template :partial => '_form'
3176
3182
3177 issue = assigns(:issue)
3183 issue = assigns(:issue)
3178 assert_kind_of Issue, issue
3184 assert_kind_of Issue, issue
3179 assert_equal 1, issue.id
3185 assert_equal 1, issue.id
3180 assert_equal 1, issue.project_id
3186 assert_equal 1, issue.project_id
3181 assert_equal 2, issue.tracker_id
3187 assert_equal 2, issue.tracker_id
3182 assert_equal 'This is the test_new issue', issue.subject
3188 assert_equal 'This is the test_new issue', issue.subject
3183 end
3189 end
3184
3190
3185 def test_update_form_for_existing_issue_should_keep_issue_author
3191 def test_update_form_for_existing_issue_should_keep_issue_author
3186 @request.session[:user_id] = 3
3192 @request.session[:user_id] = 3
3187 xhr :patch, :edit, :id => 1, :issue => {:subject => 'Changed'}
3193 xhr :patch, :edit, :id => 1, :issue => {:subject => 'Changed'}
3188 assert_response :success
3194 assert_response :success
3189 assert_equal 'text/javascript', response.content_type
3195 assert_equal 'text/javascript', response.content_type
3190
3196
3191 issue = assigns(:issue)
3197 issue = assigns(:issue)
3192 assert_equal User.find(2), issue.author
3198 assert_equal User.find(2), issue.author
3193 assert_equal 2, issue.author_id
3199 assert_equal 2, issue.author_id
3194 assert_not_equal User.current, issue.author
3200 assert_not_equal User.current, issue.author
3195 end
3201 end
3196
3202
3197 def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
3203 def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
3198 @request.session[:user_id] = 2
3204 @request.session[:user_id] = 2
3199 WorkflowTransition.delete_all
3205 WorkflowTransition.delete_all
3200 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3206 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3201 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3207 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3202 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
3208 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
3203
3209
3204 xhr :patch, :edit, :id => 2,
3210 xhr :patch, :edit, :id => 2,
3205 :issue => {:tracker_id => 2,
3211 :issue => {:tracker_id => 2,
3206 :status_id => 5,
3212 :status_id => 5,
3207 :subject => 'This is an issue'}
3213 :subject => 'This is an issue'}
3208
3214
3209 assert_equal 5, assigns(:issue).status_id
3215 assert_equal 5, assigns(:issue).status_id
3210 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
3216 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
3211 end
3217 end
3212
3218
3213 def test_update_form_for_existing_issue_with_project_change
3219 def test_update_form_for_existing_issue_with_project_change
3214 @request.session[:user_id] = 2
3220 @request.session[:user_id] = 2
3215 xhr :patch, :edit, :id => 1,
3221 xhr :patch, :edit, :id => 1,
3216 :issue => {:project_id => 2,
3222 :issue => {:project_id => 2,
3217 :tracker_id => 2,
3223 :tracker_id => 2,
3218 :subject => 'This is the test_new issue',
3224 :subject => 'This is the test_new issue',
3219 :description => 'This is the description',
3225 :description => 'This is the description',
3220 :priority_id => 5}
3226 :priority_id => 5}
3221 assert_response :success
3227 assert_response :success
3222 assert_template :partial => '_form'
3228 assert_template :partial => '_form'
3223
3229
3224 issue = assigns(:issue)
3230 issue = assigns(:issue)
3225 assert_kind_of Issue, issue
3231 assert_kind_of Issue, issue
3226 assert_equal 1, issue.id
3232 assert_equal 1, issue.id
3227 assert_equal 2, issue.project_id
3233 assert_equal 2, issue.project_id
3228 assert_equal 2, issue.tracker_id
3234 assert_equal 2, issue.tracker_id
3229 assert_equal 'This is the test_new issue', issue.subject
3235 assert_equal 'This is the test_new issue', issue.subject
3230 end
3236 end
3231
3237
3232 def test_update_form_should_keep_category_with_same_when_changing_project
3238 def test_update_form_should_keep_category_with_same_when_changing_project
3233 source = Project.generate!
3239 source = Project.generate!
3234 target = Project.generate!
3240 target = Project.generate!
3235 source_category = IssueCategory.create!(:name => 'Foo', :project => source)
3241 source_category = IssueCategory.create!(:name => 'Foo', :project => source)
3236 target_category = IssueCategory.create!(:name => 'Foo', :project => target)
3242 target_category = IssueCategory.create!(:name => 'Foo', :project => target)
3237 issue = Issue.generate!(:project => source, :category => source_category)
3243 issue = Issue.generate!(:project => source, :category => source_category)
3238
3244
3239 @request.session[:user_id] = 1
3245 @request.session[:user_id] = 1
3240 patch :edit, :id => issue.id,
3246 patch :edit, :id => issue.id,
3241 :issue => {:project_id => target.id, :category_id => source_category.id}
3247 :issue => {:project_id => target.id, :category_id => source_category.id}
3242 assert_response :success
3248 assert_response :success
3243
3249
3244 issue = assigns(:issue)
3250 issue = assigns(:issue)
3245 assert_equal target_category, issue.category
3251 assert_equal target_category, issue.category
3246 end
3252 end
3247
3253
3248 def test_update_form_should_propose_default_status_for_existing_issue
3254 def test_update_form_should_propose_default_status_for_existing_issue
3249 @request.session[:user_id] = 2
3255 @request.session[:user_id] = 2
3250 WorkflowTransition.delete_all
3256 WorkflowTransition.delete_all
3251 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3257 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3252
3258
3253 xhr :patch, :edit, :id => 2
3259 xhr :patch, :edit, :id => 2
3254 assert_response :success
3260 assert_response :success
3255 assert_equal [2,3], assigns(:allowed_statuses).map(&:id).sort
3261 assert_equal [2,3], assigns(:allowed_statuses).map(&:id).sort
3256 end
3262 end
3257
3263
3258 def test_put_update_without_custom_fields_param
3264 def test_put_update_without_custom_fields_param
3259 @request.session[:user_id] = 2
3265 @request.session[:user_id] = 2
3260
3266
3261 issue = Issue.find(1)
3267 issue = Issue.find(1)
3262 assert_equal '125', issue.custom_value_for(2).value
3268 assert_equal '125', issue.custom_value_for(2).value
3263
3269
3264 assert_difference('Journal.count') do
3270 assert_difference('Journal.count') do
3265 assert_difference('JournalDetail.count') do
3271 assert_difference('JournalDetail.count') do
3266 put :update, :id => 1, :issue => {:subject => 'New subject'}
3272 put :update, :id => 1, :issue => {:subject => 'New subject'}
3267 end
3273 end
3268 end
3274 end
3269 assert_redirected_to :action => 'show', :id => '1'
3275 assert_redirected_to :action => 'show', :id => '1'
3270 issue.reload
3276 issue.reload
3271 assert_equal 'New subject', issue.subject
3277 assert_equal 'New subject', issue.subject
3272 # Make sure custom fields were not cleared
3278 # Make sure custom fields were not cleared
3273 assert_equal '125', issue.custom_value_for(2).value
3279 assert_equal '125', issue.custom_value_for(2).value
3274 end
3280 end
3275
3281
3276 def test_put_update_with_project_change
3282 def test_put_update_with_project_change
3277 @request.session[:user_id] = 2
3283 @request.session[:user_id] = 2
3278 ActionMailer::Base.deliveries.clear
3284 ActionMailer::Base.deliveries.clear
3279
3285
3280 with_settings :notified_events => %w(issue_updated) do
3286 with_settings :notified_events => %w(issue_updated) do
3281 assert_difference('Journal.count') do
3287 assert_difference('Journal.count') do
3282 assert_difference('JournalDetail.count', 3) do
3288 assert_difference('JournalDetail.count', 3) do
3283 put :update, :id => 1, :issue => {:project_id => '2',
3289 put :update, :id => 1, :issue => {:project_id => '2',
3284 :tracker_id => '1', # no change
3290 :tracker_id => '1', # no change
3285 :priority_id => '6',
3291 :priority_id => '6',
3286 :category_id => '3'
3292 :category_id => '3'
3287 }
3293 }
3288 end
3294 end
3289 end
3295 end
3290 end
3296 end
3291 assert_redirected_to :action => 'show', :id => '1'
3297 assert_redirected_to :action => 'show', :id => '1'
3292 issue = Issue.find(1)
3298 issue = Issue.find(1)
3293 assert_equal 2, issue.project_id
3299 assert_equal 2, issue.project_id
3294 assert_equal 1, issue.tracker_id
3300 assert_equal 1, issue.tracker_id
3295 assert_equal 6, issue.priority_id
3301 assert_equal 6, issue.priority_id
3296 assert_equal 3, issue.category_id
3302 assert_equal 3, issue.category_id
3297
3303
3298 mail = ActionMailer::Base.deliveries.last
3304 mail = ActionMailer::Base.deliveries.last
3299 assert_not_nil mail
3305 assert_not_nil mail
3300 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3306 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3301 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
3307 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
3302 end
3308 end
3303
3309
3304 def test_put_update_trying_to_move_issue_to_project_without_tracker_should_not_error
3310 def test_put_update_trying_to_move_issue_to_project_without_tracker_should_not_error
3305 target = Project.generate!(:tracker_ids => [])
3311 target = Project.generate!(:tracker_ids => [])
3306 assert target.trackers.empty?
3312 assert target.trackers.empty?
3307 issue = Issue.generate!
3313 issue = Issue.generate!
3308 @request.session[:user_id] = 1
3314 @request.session[:user_id] = 1
3309
3315
3310 put :update, :id => issue.id, :issue => {:project_id => target.id}
3316 put :update, :id => issue.id, :issue => {:project_id => target.id}
3311 assert_response 302
3317 assert_response 302
3312 end
3318 end
3313
3319
3314 def test_put_update_with_tracker_change
3320 def test_put_update_with_tracker_change
3315 @request.session[:user_id] = 2
3321 @request.session[:user_id] = 2
3316 ActionMailer::Base.deliveries.clear
3322 ActionMailer::Base.deliveries.clear
3317
3323
3318 with_settings :notified_events => %w(issue_updated) do
3324 with_settings :notified_events => %w(issue_updated) do
3319 assert_difference('Journal.count') do
3325 assert_difference('Journal.count') do
3320 assert_difference('JournalDetail.count', 2) do
3326 assert_difference('JournalDetail.count', 2) do
3321 put :update, :id => 1, :issue => {:project_id => '1',
3327 put :update, :id => 1, :issue => {:project_id => '1',
3322 :tracker_id => '2',
3328 :tracker_id => '2',
3323 :priority_id => '6'
3329 :priority_id => '6'
3324 }
3330 }
3325 end
3331 end
3326 end
3332 end
3327 end
3333 end
3328 assert_redirected_to :action => 'show', :id => '1'
3334 assert_redirected_to :action => 'show', :id => '1'
3329 issue = Issue.find(1)
3335 issue = Issue.find(1)
3330 assert_equal 1, issue.project_id
3336 assert_equal 1, issue.project_id
3331 assert_equal 2, issue.tracker_id
3337 assert_equal 2, issue.tracker_id
3332 assert_equal 6, issue.priority_id
3338 assert_equal 6, issue.priority_id
3333 assert_equal 1, issue.category_id
3339 assert_equal 1, issue.category_id
3334
3340
3335 mail = ActionMailer::Base.deliveries.last
3341 mail = ActionMailer::Base.deliveries.last
3336 assert_not_nil mail
3342 assert_not_nil mail
3337 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3343 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3338 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
3344 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
3339 end
3345 end
3340
3346
3341 def test_put_update_with_custom_field_change
3347 def test_put_update_with_custom_field_change
3342 @request.session[:user_id] = 2
3348 @request.session[:user_id] = 2
3343 issue = Issue.find(1)
3349 issue = Issue.find(1)
3344 assert_equal '125', issue.custom_value_for(2).value
3350 assert_equal '125', issue.custom_value_for(2).value
3345
3351
3346 with_settings :notified_events => %w(issue_updated) do
3352 with_settings :notified_events => %w(issue_updated) do
3347 assert_difference('Journal.count') do
3353 assert_difference('Journal.count') do
3348 assert_difference('JournalDetail.count', 3) do
3354 assert_difference('JournalDetail.count', 3) do
3349 put :update, :id => 1, :issue => {:subject => 'Custom field change',
3355 put :update, :id => 1, :issue => {:subject => 'Custom field change',
3350 :priority_id => '6',
3356 :priority_id => '6',
3351 :category_id => '1', # no change
3357 :category_id => '1', # no change
3352 :custom_field_values => { '2' => 'New custom value' }
3358 :custom_field_values => { '2' => 'New custom value' }
3353 }
3359 }
3354 end
3360 end
3355 end
3361 end
3356 end
3362 end
3357 assert_redirected_to :action => 'show', :id => '1'
3363 assert_redirected_to :action => 'show', :id => '1'
3358 issue.reload
3364 issue.reload
3359 assert_equal 'New custom value', issue.custom_value_for(2).value
3365 assert_equal 'New custom value', issue.custom_value_for(2).value
3360
3366
3361 mail = ActionMailer::Base.deliveries.last
3367 mail = ActionMailer::Base.deliveries.last
3362 assert_not_nil mail
3368 assert_not_nil mail
3363 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
3369 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
3364 end
3370 end
3365
3371
3366 def test_put_update_with_multi_custom_field_change
3372 def test_put_update_with_multi_custom_field_change
3367 field = CustomField.find(1)
3373 field = CustomField.find(1)
3368 field.update_attribute :multiple, true
3374 field.update_attribute :multiple, true
3369 issue = Issue.find(1)
3375 issue = Issue.find(1)
3370 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3376 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3371 issue.save!
3377 issue.save!
3372
3378
3373 @request.session[:user_id] = 2
3379 @request.session[:user_id] = 2
3374 assert_difference('Journal.count') do
3380 assert_difference('Journal.count') do
3375 assert_difference('JournalDetail.count', 3) do
3381 assert_difference('JournalDetail.count', 3) do
3376 put :update, :id => 1,
3382 put :update, :id => 1,
3377 :issue => {
3383 :issue => {
3378 :subject => 'Custom field change',
3384 :subject => 'Custom field change',
3379 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
3385 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
3380 }
3386 }
3381 end
3387 end
3382 end
3388 end
3383 assert_redirected_to :action => 'show', :id => '1'
3389 assert_redirected_to :action => 'show', :id => '1'
3384 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
3390 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
3385 end
3391 end
3386
3392
3387 def test_put_update_with_status_and_assignee_change
3393 def test_put_update_with_status_and_assignee_change
3388 issue = Issue.find(1)
3394 issue = Issue.find(1)
3389 assert_equal 1, issue.status_id
3395 assert_equal 1, issue.status_id
3390 @request.session[:user_id] = 2
3396 @request.session[:user_id] = 2
3391
3397
3392 with_settings :notified_events => %w(issue_updated) do
3398 with_settings :notified_events => %w(issue_updated) do
3393 assert_difference('TimeEntry.count', 0) do
3399 assert_difference('TimeEntry.count', 0) do
3394 put :update,
3400 put :update,
3395 :id => 1,
3401 :id => 1,
3396 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
3402 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
3397 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
3403 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
3398 end
3404 end
3399 end
3405 end
3400 assert_redirected_to :action => 'show', :id => '1'
3406 assert_redirected_to :action => 'show', :id => '1'
3401 issue.reload
3407 issue.reload
3402 assert_equal 2, issue.status_id
3408 assert_equal 2, issue.status_id
3403 j = Journal.order('id DESC').first
3409 j = Journal.order('id DESC').first
3404 assert_equal 'Assigned to dlopper', j.notes
3410 assert_equal 'Assigned to dlopper', j.notes
3405 assert_equal 2, j.details.size
3411 assert_equal 2, j.details.size
3406
3412
3407 mail = ActionMailer::Base.deliveries.last
3413 mail = ActionMailer::Base.deliveries.last
3408 assert_mail_body_match "Status changed from New to Assigned", mail
3414 assert_mail_body_match "Status changed from New to Assigned", mail
3409 # subject should contain the new status
3415 # subject should contain the new status
3410 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
3416 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
3411 end
3417 end
3412
3418
3413 def test_put_update_with_note_only
3419 def test_put_update_with_note_only
3414 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
3420 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
3415
3421
3416 with_settings :notified_events => %w(issue_updated) do
3422 with_settings :notified_events => %w(issue_updated) do
3417 # anonymous user
3423 # anonymous user
3418 put :update,
3424 put :update,
3419 :id => 1,
3425 :id => 1,
3420 :issue => { :notes => notes }
3426 :issue => { :notes => notes }
3421 end
3427 end
3422 assert_redirected_to :action => 'show', :id => '1'
3428 assert_redirected_to :action => 'show', :id => '1'
3423 j = Journal.order('id DESC').first
3429 j = Journal.order('id DESC').first
3424 assert_equal notes, j.notes
3430 assert_equal notes, j.notes
3425 assert_equal 0, j.details.size
3431 assert_equal 0, j.details.size
3426 assert_equal User.anonymous, j.user
3432 assert_equal User.anonymous, j.user
3427
3433
3428 mail = ActionMailer::Base.deliveries.last
3434 mail = ActionMailer::Base.deliveries.last
3429 assert_mail_body_match notes, mail
3435 assert_mail_body_match notes, mail
3430 end
3436 end
3431
3437
3432 def test_put_update_with_private_note_only
3438 def test_put_update_with_private_note_only
3433 notes = 'Private note'
3439 notes = 'Private note'
3434 @request.session[:user_id] = 2
3440 @request.session[:user_id] = 2
3435
3441
3436 assert_difference 'Journal.count' do
3442 assert_difference 'Journal.count' do
3437 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
3443 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
3438 assert_redirected_to :action => 'show', :id => '1'
3444 assert_redirected_to :action => 'show', :id => '1'
3439 end
3445 end
3440
3446
3441 j = Journal.order('id DESC').first
3447 j = Journal.order('id DESC').first
3442 assert_equal notes, j.notes
3448 assert_equal notes, j.notes
3443 assert_equal true, j.private_notes
3449 assert_equal true, j.private_notes
3444 end
3450 end
3445
3451
3446 def test_put_update_with_private_note_and_changes
3452 def test_put_update_with_private_note_and_changes
3447 notes = 'Private note'
3453 notes = 'Private note'
3448 @request.session[:user_id] = 2
3454 @request.session[:user_id] = 2
3449
3455
3450 assert_difference 'Journal.count', 2 do
3456 assert_difference 'Journal.count', 2 do
3451 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
3457 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
3452 assert_redirected_to :action => 'show', :id => '1'
3458 assert_redirected_to :action => 'show', :id => '1'
3453 end
3459 end
3454
3460
3455 j = Journal.order('id DESC').first
3461 j = Journal.order('id DESC').first
3456 assert_equal notes, j.notes
3462 assert_equal notes, j.notes
3457 assert_equal true, j.private_notes
3463 assert_equal true, j.private_notes
3458 assert_equal 0, j.details.count
3464 assert_equal 0, j.details.count
3459
3465
3460 j = Journal.order('id DESC').offset(1).first
3466 j = Journal.order('id DESC').offset(1).first
3461 assert_nil j.notes
3467 assert_nil j.notes
3462 assert_equal false, j.private_notes
3468 assert_equal false, j.private_notes
3463 assert_equal 1, j.details.count
3469 assert_equal 1, j.details.count
3464 end
3470 end
3465
3471
3466 def test_put_update_with_note_and_spent_time
3472 def test_put_update_with_note_and_spent_time
3467 @request.session[:user_id] = 2
3473 @request.session[:user_id] = 2
3468 spent_hours_before = Issue.find(1).spent_hours
3474 spent_hours_before = Issue.find(1).spent_hours
3469 assert_difference('TimeEntry.count') do
3475 assert_difference('TimeEntry.count') do
3470 put :update,
3476 put :update,
3471 :id => 1,
3477 :id => 1,
3472 :issue => { :notes => '2.5 hours added' },
3478 :issue => { :notes => '2.5 hours added' },
3473 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
3479 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
3474 end
3480 end
3475 assert_redirected_to :action => 'show', :id => '1'
3481 assert_redirected_to :action => 'show', :id => '1'
3476
3482
3477 issue = Issue.find(1)
3483 issue = Issue.find(1)
3478
3484
3479 j = Journal.order('id DESC').first
3485 j = Journal.order('id DESC').first
3480 assert_equal '2.5 hours added', j.notes
3486 assert_equal '2.5 hours added', j.notes
3481 assert_equal 0, j.details.size
3487 assert_equal 0, j.details.size
3482
3488
3483 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
3489 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
3484 assert_not_nil t
3490 assert_not_nil t
3485 assert_equal 2.5, t.hours
3491 assert_equal 2.5, t.hours
3486 assert_equal spent_hours_before + 2.5, issue.spent_hours
3492 assert_equal spent_hours_before + 2.5, issue.spent_hours
3487 end
3493 end
3488
3494
3489 def test_put_update_should_preserve_parent_issue_even_if_not_visible
3495 def test_put_update_should_preserve_parent_issue_even_if_not_visible
3490 parent = Issue.generate!(:project_id => 1, :is_private => true)
3496 parent = Issue.generate!(:project_id => 1, :is_private => true)
3491 issue = Issue.generate!(:parent_issue_id => parent.id)
3497 issue = Issue.generate!(:parent_issue_id => parent.id)
3492 assert !parent.visible?(User.find(3))
3498 assert !parent.visible?(User.find(3))
3493 @request.session[:user_id] = 3
3499 @request.session[:user_id] = 3
3494
3500
3495 get :edit, :id => issue.id
3501 get :edit, :id => issue.id
3496 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
3502 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
3497
3503
3498 put :update, :id => issue.id, :issue => {:subject => 'New subject', :parent_issue_id => parent.id.to_s}
3504 put :update, :id => issue.id, :issue => {:subject => 'New subject', :parent_issue_id => parent.id.to_s}
3499 assert_response 302
3505 assert_response 302
3500 assert_equal parent, issue.parent
3506 assert_equal parent, issue.parent
3501 end
3507 end
3502
3508
3503 def test_put_update_with_attachment_only
3509 def test_put_update_with_attachment_only
3504 set_tmp_attachments_directory
3510 set_tmp_attachments_directory
3505
3511
3506 # Delete all fixtured journals, a race condition can occur causing the wrong
3512 # Delete all fixtured journals, a race condition can occur causing the wrong
3507 # journal to get fetched in the next find.
3513 # journal to get fetched in the next find.
3508 Journal.delete_all
3514 Journal.delete_all
3509
3515
3510 with_settings :notified_events => %w(issue_updated) do
3516 with_settings :notified_events => %w(issue_updated) do
3511 # anonymous user
3517 # anonymous user
3512 assert_difference 'Attachment.count' do
3518 assert_difference 'Attachment.count' do
3513 put :update, :id => 1,
3519 put :update, :id => 1,
3514 :issue => {:notes => ''},
3520 :issue => {:notes => ''},
3515 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3521 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3516 end
3522 end
3517 end
3523 end
3518
3524
3519 assert_redirected_to :action => 'show', :id => '1'
3525 assert_redirected_to :action => 'show', :id => '1'
3520 j = Issue.find(1).journals.reorder('id DESC').first
3526 j = Issue.find(1).journals.reorder('id DESC').first
3521 assert j.notes.blank?
3527 assert j.notes.blank?
3522 assert_equal 1, j.details.size
3528 assert_equal 1, j.details.size
3523 assert_equal 'testfile.txt', j.details.first.value
3529 assert_equal 'testfile.txt', j.details.first.value
3524 assert_equal User.anonymous, j.user
3530 assert_equal User.anonymous, j.user
3525
3531
3526 attachment = Attachment.order('id DESC').first
3532 attachment = Attachment.order('id DESC').first
3527 assert_equal Issue.find(1), attachment.container
3533 assert_equal Issue.find(1), attachment.container
3528 assert_equal User.anonymous, attachment.author
3534 assert_equal User.anonymous, attachment.author
3529 assert_equal 'testfile.txt', attachment.filename
3535 assert_equal 'testfile.txt', attachment.filename
3530 assert_equal 'text/plain', attachment.content_type
3536 assert_equal 'text/plain', attachment.content_type
3531 assert_equal 'test file', attachment.description
3537 assert_equal 'test file', attachment.description
3532 assert_equal 59, attachment.filesize
3538 assert_equal 59, attachment.filesize
3533 assert File.exists?(attachment.diskfile)
3539 assert File.exists?(attachment.diskfile)
3534 assert_equal 59, File.size(attachment.diskfile)
3540 assert_equal 59, File.size(attachment.diskfile)
3535
3541
3536 mail = ActionMailer::Base.deliveries.last
3542 mail = ActionMailer::Base.deliveries.last
3537 assert_mail_body_match 'testfile.txt', mail
3543 assert_mail_body_match 'testfile.txt', mail
3538 end
3544 end
3539
3545
3540 def test_put_update_with_failure_should_save_attachments
3546 def test_put_update_with_failure_should_save_attachments
3541 set_tmp_attachments_directory
3547 set_tmp_attachments_directory
3542 @request.session[:user_id] = 2
3548 @request.session[:user_id] = 2
3543
3549
3544 assert_no_difference 'Journal.count' do
3550 assert_no_difference 'Journal.count' do
3545 assert_difference 'Attachment.count' do
3551 assert_difference 'Attachment.count' do
3546 put :update, :id => 1,
3552 put :update, :id => 1,
3547 :issue => { :subject => '' },
3553 :issue => { :subject => '' },
3548 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3554 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3549 assert_response :success
3555 assert_response :success
3550 assert_template 'edit'
3556 assert_template 'edit'
3551 end
3557 end
3552 end
3558 end
3553
3559
3554 attachment = Attachment.order('id DESC').first
3560 attachment = Attachment.order('id DESC').first
3555 assert_equal 'testfile.txt', attachment.filename
3561 assert_equal 'testfile.txt', attachment.filename
3556 assert File.exists?(attachment.diskfile)
3562 assert File.exists?(attachment.diskfile)
3557 assert_nil attachment.container
3563 assert_nil attachment.container
3558
3564
3559 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3565 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3560 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3566 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3561 end
3567 end
3562
3568
3563 def test_put_update_with_failure_should_keep_saved_attachments
3569 def test_put_update_with_failure_should_keep_saved_attachments
3564 set_tmp_attachments_directory
3570 set_tmp_attachments_directory
3565 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3571 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3566 @request.session[:user_id] = 2
3572 @request.session[:user_id] = 2
3567
3573
3568 assert_no_difference 'Journal.count' do
3574 assert_no_difference 'Journal.count' do
3569 assert_no_difference 'Attachment.count' do
3575 assert_no_difference 'Attachment.count' do
3570 put :update, :id => 1,
3576 put :update, :id => 1,
3571 :issue => { :subject => '' },
3577 :issue => { :subject => '' },
3572 :attachments => {'p0' => {'token' => attachment.token}}
3578 :attachments => {'p0' => {'token' => attachment.token}}
3573 assert_response :success
3579 assert_response :success
3574 assert_template 'edit'
3580 assert_template 'edit'
3575 end
3581 end
3576 end
3582 end
3577
3583
3578 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3584 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3579 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3585 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3580 end
3586 end
3581
3587
3582 def test_put_update_should_attach_saved_attachments
3588 def test_put_update_should_attach_saved_attachments
3583 set_tmp_attachments_directory
3589 set_tmp_attachments_directory
3584 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3590 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3585 @request.session[:user_id] = 2
3591 @request.session[:user_id] = 2
3586
3592
3587 assert_difference 'Journal.count' do
3593 assert_difference 'Journal.count' do
3588 assert_difference 'JournalDetail.count' do
3594 assert_difference 'JournalDetail.count' do
3589 assert_no_difference 'Attachment.count' do
3595 assert_no_difference 'Attachment.count' do
3590 put :update, :id => 1,
3596 put :update, :id => 1,
3591 :issue => {:notes => 'Attachment added'},
3597 :issue => {:notes => 'Attachment added'},
3592 :attachments => {'p0' => {'token' => attachment.token}}
3598 :attachments => {'p0' => {'token' => attachment.token}}
3593 assert_redirected_to '/issues/1'
3599 assert_redirected_to '/issues/1'
3594 end
3600 end
3595 end
3601 end
3596 end
3602 end
3597
3603
3598 attachment.reload
3604 attachment.reload
3599 assert_equal Issue.find(1), attachment.container
3605 assert_equal Issue.find(1), attachment.container
3600
3606
3601 journal = Journal.order('id DESC').first
3607 journal = Journal.order('id DESC').first
3602 assert_equal 1, journal.details.size
3608 assert_equal 1, journal.details.size
3603 assert_equal 'testfile.txt', journal.details.first.value
3609 assert_equal 'testfile.txt', journal.details.first.value
3604 end
3610 end
3605
3611
3606 def test_put_update_with_attachment_that_fails_to_save
3612 def test_put_update_with_attachment_that_fails_to_save
3607 set_tmp_attachments_directory
3613 set_tmp_attachments_directory
3608
3614
3609 # anonymous user
3615 # anonymous user
3610 with_settings :attachment_max_size => 0 do
3616 with_settings :attachment_max_size => 0 do
3611 put :update,
3617 put :update,
3612 :id => 1,
3618 :id => 1,
3613 :issue => {:notes => ''},
3619 :issue => {:notes => ''},
3614 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
3620 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
3615 assert_redirected_to :action => 'show', :id => '1'
3621 assert_redirected_to :action => 'show', :id => '1'
3616 assert_equal '1 file(s) could not be saved.', flash[:warning]
3622 assert_equal '1 file(s) could not be saved.', flash[:warning]
3617 end
3623 end
3618 end
3624 end
3619
3625
3620 def test_put_update_with_no_change
3626 def test_put_update_with_no_change
3621 issue = Issue.find(1)
3627 issue = Issue.find(1)
3622 issue.journals.clear
3628 issue.journals.clear
3623 ActionMailer::Base.deliveries.clear
3629 ActionMailer::Base.deliveries.clear
3624
3630
3625 put :update,
3631 put :update,
3626 :id => 1,
3632 :id => 1,
3627 :issue => {:notes => ''}
3633 :issue => {:notes => ''}
3628 assert_redirected_to :action => 'show', :id => '1'
3634 assert_redirected_to :action => 'show', :id => '1'
3629
3635
3630 issue.reload
3636 issue.reload
3631 assert issue.journals.empty?
3637 assert issue.journals.empty?
3632 # No email should be sent
3638 # No email should be sent
3633 assert ActionMailer::Base.deliveries.empty?
3639 assert ActionMailer::Base.deliveries.empty?
3634 end
3640 end
3635
3641
3636 def test_put_update_should_send_a_notification
3642 def test_put_update_should_send_a_notification
3637 @request.session[:user_id] = 2
3643 @request.session[:user_id] = 2
3638 ActionMailer::Base.deliveries.clear
3644 ActionMailer::Base.deliveries.clear
3639 issue = Issue.find(1)
3645 issue = Issue.find(1)
3640 old_subject = issue.subject
3646 old_subject = issue.subject
3641 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3647 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3642
3648
3643 with_settings :notified_events => %w(issue_updated) do
3649 with_settings :notified_events => %w(issue_updated) do
3644 put :update, :id => 1, :issue => {:subject => new_subject,
3650 put :update, :id => 1, :issue => {:subject => new_subject,
3645 :priority_id => '6',
3651 :priority_id => '6',
3646 :category_id => '1' # no change
3652 :category_id => '1' # no change
3647 }
3653 }
3648 assert_equal 1, ActionMailer::Base.deliveries.size
3654 assert_equal 1, ActionMailer::Base.deliveries.size
3649 end
3655 end
3650 end
3656 end
3651
3657
3652 def test_put_update_with_invalid_spent_time_hours_only
3658 def test_put_update_with_invalid_spent_time_hours_only
3653 @request.session[:user_id] = 2
3659 @request.session[:user_id] = 2
3654 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3660 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3655
3661
3656 assert_no_difference('Journal.count') do
3662 assert_no_difference('Journal.count') do
3657 put :update,
3663 put :update,
3658 :id => 1,
3664 :id => 1,
3659 :issue => {:notes => notes},
3665 :issue => {:notes => notes},
3660 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3666 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3661 end
3667 end
3662 assert_response :success
3668 assert_response :success
3663 assert_template 'edit'
3669 assert_template 'edit'
3664
3670
3665 assert_select_error /Activity cannot be blank/
3671 assert_select_error /Activity cannot be blank/
3666 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3672 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3667 assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
3673 assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
3668 end
3674 end
3669
3675
3670 def test_put_update_with_invalid_spent_time_comments_only
3676 def test_put_update_with_invalid_spent_time_comments_only
3671 @request.session[:user_id] = 2
3677 @request.session[:user_id] = 2
3672 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3678 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3673
3679
3674 assert_no_difference('Journal.count') do
3680 assert_no_difference('Journal.count') do
3675 put :update,
3681 put :update,
3676 :id => 1,
3682 :id => 1,
3677 :issue => {:notes => notes},
3683 :issue => {:notes => notes},
3678 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3684 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3679 end
3685 end
3680 assert_response :success
3686 assert_response :success
3681 assert_template 'edit'
3687 assert_template 'edit'
3682
3688
3683 assert_select_error /Activity cannot be blank/
3689 assert_select_error /Activity cannot be blank/
3684 assert_select_error /Hours cannot be blank/
3690 assert_select_error /Hours cannot be blank/
3685 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3691 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3686 assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
3692 assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
3687 end
3693 end
3688
3694
3689 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3695 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3690 issue = Issue.find(2)
3696 issue = Issue.find(2)
3691 @request.session[:user_id] = 2
3697 @request.session[:user_id] = 2
3692
3698
3693 put :update,
3699 put :update,
3694 :id => issue.id,
3700 :id => issue.id,
3695 :issue => {
3701 :issue => {
3696 :fixed_version_id => 4
3702 :fixed_version_id => 4
3697 }
3703 }
3698
3704
3699 assert_response :redirect
3705 assert_response :redirect
3700 issue.reload
3706 issue.reload
3701 assert_equal 4, issue.fixed_version_id
3707 assert_equal 4, issue.fixed_version_id
3702 assert_not_equal issue.project_id, issue.fixed_version.project_id
3708 assert_not_equal issue.project_id, issue.fixed_version.project_id
3703 end
3709 end
3704
3710
3705 def test_put_update_should_redirect_back_using_the_back_url_parameter
3711 def test_put_update_should_redirect_back_using_the_back_url_parameter
3706 issue = Issue.find(2)
3712 issue = Issue.find(2)
3707 @request.session[:user_id] = 2
3713 @request.session[:user_id] = 2
3708
3714
3709 put :update,
3715 put :update,
3710 :id => issue.id,
3716 :id => issue.id,
3711 :issue => {
3717 :issue => {
3712 :fixed_version_id => 4
3718 :fixed_version_id => 4
3713 },
3719 },
3714 :back_url => '/issues'
3720 :back_url => '/issues'
3715
3721
3716 assert_response :redirect
3722 assert_response :redirect
3717 assert_redirected_to '/issues'
3723 assert_redirected_to '/issues'
3718 end
3724 end
3719
3725
3720 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3726 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3721 issue = Issue.find(2)
3727 issue = Issue.find(2)
3722 @request.session[:user_id] = 2
3728 @request.session[:user_id] = 2
3723
3729
3724 put :update,
3730 put :update,
3725 :id => issue.id,
3731 :id => issue.id,
3726 :issue => {
3732 :issue => {
3727 :fixed_version_id => 4
3733 :fixed_version_id => 4
3728 },
3734 },
3729 :back_url => 'http://google.com'
3735 :back_url => 'http://google.com'
3730
3736
3731 assert_response :redirect
3737 assert_response :redirect
3732 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3738 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3733 end
3739 end
3734
3740
3735 def test_put_update_should_redirect_with_previous_and_next_issue_ids_params
3741 def test_put_update_should_redirect_with_previous_and_next_issue_ids_params
3736 @request.session[:user_id] = 2
3742 @request.session[:user_id] = 2
3737
3743
3738 put :update, :id => 11,
3744 put :update, :id => 11,
3739 :issue => {:status_id => 6, :notes => 'Notes'},
3745 :issue => {:status_id => 6, :notes => 'Notes'},
3740 :prev_issue_id => 8,
3746 :prev_issue_id => 8,
3741 :next_issue_id => 12,
3747 :next_issue_id => 12,
3742 :issue_position => 2,
3748 :issue_position => 2,
3743 :issue_count => 3
3749 :issue_count => 3
3744
3750
3745 assert_redirected_to '/issues/11?issue_count=3&issue_position=2&next_issue_id=12&prev_issue_id=8'
3751 assert_redirected_to '/issues/11?issue_count=3&issue_position=2&next_issue_id=12&prev_issue_id=8'
3746 end
3752 end
3747
3753
3748 def test_get_bulk_edit
3754 def test_get_bulk_edit
3749 @request.session[:user_id] = 2
3755 @request.session[:user_id] = 2
3750 get :bulk_edit, :ids => [1, 3]
3756 get :bulk_edit, :ids => [1, 3]
3751 assert_response :success
3757 assert_response :success
3752 assert_template 'bulk_edit'
3758 assert_template 'bulk_edit'
3753
3759
3754 assert_select 'ul#bulk-selection' do
3760 assert_select 'ul#bulk-selection' do
3755 assert_select 'li', 2
3761 assert_select 'li', 2
3756 assert_select 'li a', :text => 'Bug #1'
3762 assert_select 'li a', :text => 'Bug #1'
3757 end
3763 end
3758
3764
3759 assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
3765 assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
3760 assert_select 'input[name=?]', 'ids[]', 2
3766 assert_select 'input[name=?]', 'ids[]', 2
3761 assert_select 'input[name=?][value="1"][type=hidden]', 'ids[]'
3767 assert_select 'input[name=?][value="1"][type=hidden]', 'ids[]'
3762
3768
3763 assert_select 'select[name=?]', 'issue[project_id]'
3769 assert_select 'select[name=?]', 'issue[project_id]'
3764 assert_select 'input[name=?]', 'issue[parent_issue_id]'
3770 assert_select 'input[name=?]', 'issue[parent_issue_id]'
3765
3771
3766 # Project specific custom field, date type
3772 # Project specific custom field, date type
3767 field = CustomField.find(9)
3773 field = CustomField.find(9)
3768 assert !field.is_for_all?
3774 assert !field.is_for_all?
3769 assert_equal 'date', field.field_format
3775 assert_equal 'date', field.field_format
3770 assert_select 'input[name=?]', 'issue[custom_field_values][9]'
3776 assert_select 'input[name=?]', 'issue[custom_field_values][9]'
3771
3777
3772 # System wide custom field
3778 # System wide custom field
3773 assert CustomField.find(1).is_for_all?
3779 assert CustomField.find(1).is_for_all?
3774 assert_select 'select[name=?]', 'issue[custom_field_values][1]'
3780 assert_select 'select[name=?]', 'issue[custom_field_values][1]'
3775
3781
3776 # Be sure we don't display inactive IssuePriorities
3782 # Be sure we don't display inactive IssuePriorities
3777 assert ! IssuePriority.find(15).active?
3783 assert ! IssuePriority.find(15).active?
3778 assert_select 'select[name=?]', 'issue[priority_id]' do
3784 assert_select 'select[name=?]', 'issue[priority_id]' do
3779 assert_select 'option[value="15"]', 0
3785 assert_select 'option[value="15"]', 0
3780 end
3786 end
3781 end
3787 end
3782 end
3788 end
3783
3789
3784 def test_get_bulk_edit_on_different_projects
3790 def test_get_bulk_edit_on_different_projects
3785 @request.session[:user_id] = 2
3791 @request.session[:user_id] = 2
3786 get :bulk_edit, :ids => [1, 2, 6]
3792 get :bulk_edit, :ids => [1, 2, 6]
3787 assert_response :success
3793 assert_response :success
3788 assert_template 'bulk_edit'
3794 assert_template 'bulk_edit'
3789
3795
3790 # Can not set issues from different projects as children of an issue
3796 # Can not set issues from different projects as children of an issue
3791 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
3797 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
3792
3798
3793 # Project specific custom field, date type
3799 # Project specific custom field, date type
3794 field = CustomField.find(9)
3800 field = CustomField.find(9)
3795 assert !field.is_for_all?
3801 assert !field.is_for_all?
3796 assert !field.project_ids.include?(Issue.find(6).project_id)
3802 assert !field.project_ids.include?(Issue.find(6).project_id)
3797 assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
3803 assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
3798 end
3804 end
3799
3805
3800 def test_get_bulk_edit_with_user_custom_field
3806 def test_get_bulk_edit_with_user_custom_field
3801 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :tracker_ids => [1,2,3])
3807 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :tracker_ids => [1,2,3])
3802
3808
3803 @request.session[:user_id] = 2
3809 @request.session[:user_id] = 2
3804 get :bulk_edit, :ids => [1, 2]
3810 get :bulk_edit, :ids => [1, 2]
3805 assert_response :success
3811 assert_response :success
3806 assert_template 'bulk_edit'
3812 assert_template 'bulk_edit'
3807
3813
3808 assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3814 assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3809 assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
3815 assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
3810 end
3816 end
3811 end
3817 end
3812
3818
3813 def test_get_bulk_edit_with_version_custom_field
3819 def test_get_bulk_edit_with_version_custom_field
3814 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
3820 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
3815
3821
3816 @request.session[:user_id] = 2
3822 @request.session[:user_id] = 2
3817 get :bulk_edit, :ids => [1, 2]
3823 get :bulk_edit, :ids => [1, 2]
3818 assert_response :success
3824 assert_response :success
3819 assert_template 'bulk_edit'
3825 assert_template 'bulk_edit'
3820
3826
3821 assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3827 assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3822 assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3828 assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3823 end
3829 end
3824 end
3830 end
3825
3831
3826 def test_get_bulk_edit_with_multi_custom_field
3832 def test_get_bulk_edit_with_multi_custom_field
3827 field = CustomField.find(1)
3833 field = CustomField.find(1)
3828 field.update_attribute :multiple, true
3834 field.update_attribute :multiple, true
3829
3835
3830 @request.session[:user_id] = 2
3836 @request.session[:user_id] = 2
3831 get :bulk_edit, :ids => [1, 3]
3837 get :bulk_edit, :ids => [1, 3]
3832 assert_response :success
3838 assert_response :success
3833 assert_template 'bulk_edit'
3839 assert_template 'bulk_edit'
3834
3840
3835 assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
3841 assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
3836 assert_select 'option', field.possible_values.size + 1 # "none" options
3842 assert_select 'option', field.possible_values.size + 1 # "none" options
3837 end
3843 end
3838 end
3844 end
3839
3845
3840 def test_bulk_edit_should_propose_to_clear_text_custom_fields
3846 def test_bulk_edit_should_propose_to_clear_text_custom_fields
3841 @request.session[:user_id] = 2
3847 @request.session[:user_id] = 2
3842 get :bulk_edit, :ids => [1, 3]
3848 get :bulk_edit, :ids => [1, 3]
3843 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', '__none__'
3849 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', '__none__'
3844 end
3850 end
3845
3851
3846 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3852 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3847 WorkflowTransition.delete_all
3853 WorkflowTransition.delete_all
3848 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3854 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3849 :old_status_id => 1, :new_status_id => 1)
3855 :old_status_id => 1, :new_status_id => 1)
3850 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3856 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3851 :old_status_id => 1, :new_status_id => 3)
3857 :old_status_id => 1, :new_status_id => 3)
3852 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3858 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3853 :old_status_id => 1, :new_status_id => 4)
3859 :old_status_id => 1, :new_status_id => 4)
3854 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3860 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3855 :old_status_id => 2, :new_status_id => 1)
3861 :old_status_id => 2, :new_status_id => 1)
3856 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3862 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3857 :old_status_id => 2, :new_status_id => 3)
3863 :old_status_id => 2, :new_status_id => 3)
3858 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3864 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3859 :old_status_id => 2, :new_status_id => 5)
3865 :old_status_id => 2, :new_status_id => 5)
3860 @request.session[:user_id] = 2
3866 @request.session[:user_id] = 2
3861 get :bulk_edit, :ids => [1, 2]
3867 get :bulk_edit, :ids => [1, 2]
3862
3868
3863 assert_response :success
3869 assert_response :success
3864 statuses = assigns(:available_statuses)
3870 statuses = assigns(:available_statuses)
3865 assert_not_nil statuses
3871 assert_not_nil statuses
3866 assert_equal [1, 3], statuses.map(&:id).sort
3872 assert_equal [1, 3], statuses.map(&:id).sort
3867
3873
3868 assert_select 'select[name=?]', 'issue[status_id]' do
3874 assert_select 'select[name=?]', 'issue[status_id]' do
3869 assert_select 'option', 3 # 2 statuses + "no change" option
3875 assert_select 'option', 3 # 2 statuses + "no change" option
3870 end
3876 end
3871 end
3877 end
3872
3878
3873 def test_bulk_edit_should_propose_target_project_open_shared_versions
3879 def test_bulk_edit_should_propose_target_project_open_shared_versions
3874 @request.session[:user_id] = 2
3880 @request.session[:user_id] = 2
3875 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3881 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3876 assert_response :success
3882 assert_response :success
3877 assert_template 'bulk_edit'
3883 assert_template 'bulk_edit'
3878 assert_equal Project.find(1).shared_versions.open.to_a.sort, assigns(:versions).sort
3884 assert_equal Project.find(1).shared_versions.open.to_a.sort, assigns(:versions).sort
3879
3885
3880 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
3886 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
3881 assert_select 'option', :text => '2.0'
3887 assert_select 'option', :text => '2.0'
3882 end
3888 end
3883 end
3889 end
3884
3890
3885 def test_bulk_edit_should_propose_target_project_categories
3891 def test_bulk_edit_should_propose_target_project_categories
3886 @request.session[:user_id] = 2
3892 @request.session[:user_id] = 2
3887 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3893 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3888 assert_response :success
3894 assert_response :success
3889 assert_template 'bulk_edit'
3895 assert_template 'bulk_edit'
3890 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3896 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3891
3897
3892 assert_select 'select[name=?]', 'issue[category_id]' do
3898 assert_select 'select[name=?]', 'issue[category_id]' do
3893 assert_select 'option', :text => 'Recipes'
3899 assert_select 'option', :text => 'Recipes'
3894 end
3900 end
3895 end
3901 end
3896
3902
3897 def test_bulk_edit_should_only_propose_issues_trackers_custom_fields
3903 def test_bulk_edit_should_only_propose_issues_trackers_custom_fields
3898 IssueCustomField.delete_all
3904 IssueCustomField.delete_all
3899 field = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
3905 field = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
3900 IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
3906 IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
3901 @request.session[:user_id] = 2
3907 @request.session[:user_id] = 2
3902
3908
3903 issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
3909 issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
3904 get :bulk_edit, :ids => issue_ids
3910 get :bulk_edit, :ids => issue_ids
3905 assert_equal [field], assigns(:custom_fields)
3911 assert_equal [field], assigns(:custom_fields)
3906 end
3912 end
3907
3913
3908 def test_bulk_update
3914 def test_bulk_update
3909 @request.session[:user_id] = 2
3915 @request.session[:user_id] = 2
3910 # update issues priority
3916 # update issues priority
3911 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3917 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3912 :issue => {:priority_id => 7,
3918 :issue => {:priority_id => 7,
3913 :assigned_to_id => '',
3919 :assigned_to_id => '',
3914 :custom_field_values => {'2' => ''}}
3920 :custom_field_values => {'2' => ''}}
3915
3921
3916 assert_response 302
3922 assert_response 302
3917 # check that the issues were updated
3923 # check that the issues were updated
3918 assert_equal [7, 7], Issue.where(:id =>[1, 2]).collect {|i| i.priority.id}
3924 assert_equal [7, 7], Issue.where(:id =>[1, 2]).collect {|i| i.priority.id}
3919
3925
3920 issue = Issue.find(1)
3926 issue = Issue.find(1)
3921 journal = issue.journals.reorder('created_on DESC').first
3927 journal = issue.journals.reorder('created_on DESC').first
3922 assert_equal '125', issue.custom_value_for(2).value
3928 assert_equal '125', issue.custom_value_for(2).value
3923 assert_equal 'Bulk editing', journal.notes
3929 assert_equal 'Bulk editing', journal.notes
3924 assert_equal 1, journal.details.size
3930 assert_equal 1, journal.details.size
3925 end
3931 end
3926
3932
3927 def test_bulk_update_with_group_assignee
3933 def test_bulk_update_with_group_assignee
3928 group = Group.find(11)
3934 group = Group.find(11)
3929 project = Project.find(1)
3935 project = Project.find(1)
3930 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3936 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3931
3937
3932 @request.session[:user_id] = 2
3938 @request.session[:user_id] = 2
3933 # update issues assignee
3939 # update issues assignee
3934 with_settings :issue_group_assignment => '1' do
3940 with_settings :issue_group_assignment => '1' do
3935 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3941 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3936 :issue => {:priority_id => '',
3942 :issue => {:priority_id => '',
3937 :assigned_to_id => group.id,
3943 :assigned_to_id => group.id,
3938 :custom_field_values => {'2' => ''}}
3944 :custom_field_values => {'2' => ''}}
3939
3945
3940 assert_response 302
3946 assert_response 302
3941 assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
3947 assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
3942 end
3948 end
3943 end
3949 end
3944
3950
3945 def test_bulk_update_on_different_projects
3951 def test_bulk_update_on_different_projects
3946 @request.session[:user_id] = 2
3952 @request.session[:user_id] = 2
3947 # update issues priority
3953 # update issues priority
3948 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3954 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3949 :issue => {:priority_id => 7,
3955 :issue => {:priority_id => 7,
3950 :assigned_to_id => '',
3956 :assigned_to_id => '',
3951 :custom_field_values => {'2' => ''}}
3957 :custom_field_values => {'2' => ''}}
3952
3958
3953 assert_response 302
3959 assert_response 302
3954 # check that the issues were updated
3960 # check that the issues were updated
3955 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3961 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3956
3962
3957 issue = Issue.find(1)
3963 issue = Issue.find(1)
3958 journal = issue.journals.reorder('created_on DESC').first
3964 journal = issue.journals.reorder('created_on DESC').first
3959 assert_equal '125', issue.custom_value_for(2).value
3965 assert_equal '125', issue.custom_value_for(2).value
3960 assert_equal 'Bulk editing', journal.notes
3966 assert_equal 'Bulk editing', journal.notes
3961 assert_equal 1, journal.details.size
3967 assert_equal 1, journal.details.size
3962 end
3968 end
3963
3969
3964 def test_bulk_update_on_different_projects_without_rights
3970 def test_bulk_update_on_different_projects_without_rights
3965 @request.session[:user_id] = 3
3971 @request.session[:user_id] = 3
3966 user = User.find(3)
3972 user = User.find(3)
3967 action = { :controller => "issues", :action => "bulk_update" }
3973 action = { :controller => "issues", :action => "bulk_update" }
3968 assert user.allowed_to?(action, Issue.find(1).project)
3974 assert user.allowed_to?(action, Issue.find(1).project)
3969 assert ! user.allowed_to?(action, Issue.find(6).project)
3975 assert ! user.allowed_to?(action, Issue.find(6).project)
3970 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3976 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3971 :issue => {:priority_id => 7,
3977 :issue => {:priority_id => 7,
3972 :assigned_to_id => '',
3978 :assigned_to_id => '',
3973 :custom_field_values => {'2' => ''}}
3979 :custom_field_values => {'2' => ''}}
3974 assert_response 403
3980 assert_response 403
3975 assert_not_equal "Bulk should fail", Journal.last.notes
3981 assert_not_equal "Bulk should fail", Journal.last.notes
3976 end
3982 end
3977
3983
3978 def test_bullk_update_should_send_a_notification
3984 def test_bullk_update_should_send_a_notification
3979 @request.session[:user_id] = 2
3985 @request.session[:user_id] = 2
3980 ActionMailer::Base.deliveries.clear
3986 ActionMailer::Base.deliveries.clear
3981 with_settings :notified_events => %w(issue_updated) do
3987 with_settings :notified_events => %w(issue_updated) do
3982 post(:bulk_update,
3988 post(:bulk_update,
3983 {
3989 {
3984 :ids => [1, 2],
3990 :ids => [1, 2],
3985 :notes => 'Bulk editing',
3991 :notes => 'Bulk editing',
3986 :issue => {
3992 :issue => {
3987 :priority_id => 7,
3993 :priority_id => 7,
3988 :assigned_to_id => '',
3994 :assigned_to_id => '',
3989 :custom_field_values => {'2' => ''}
3995 :custom_field_values => {'2' => ''}
3990 }
3996 }
3991 })
3997 })
3992 assert_response 302
3998 assert_response 302
3993 assert_equal 2, ActionMailer::Base.deliveries.size
3999 assert_equal 2, ActionMailer::Base.deliveries.size
3994 end
4000 end
3995 end
4001 end
3996
4002
3997 def test_bulk_update_project
4003 def test_bulk_update_project
3998 @request.session[:user_id] = 2
4004 @request.session[:user_id] = 2
3999 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
4005 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
4000 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4006 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4001 # Issues moved to project 2
4007 # Issues moved to project 2
4002 assert_equal 2, Issue.find(1).project_id
4008 assert_equal 2, Issue.find(1).project_id
4003 assert_equal 2, Issue.find(2).project_id
4009 assert_equal 2, Issue.find(2).project_id
4004 # No tracker change
4010 # No tracker change
4005 assert_equal 1, Issue.find(1).tracker_id
4011 assert_equal 1, Issue.find(1).tracker_id
4006 assert_equal 2, Issue.find(2).tracker_id
4012 assert_equal 2, Issue.find(2).tracker_id
4007 end
4013 end
4008
4014
4009 def test_bulk_update_project_on_single_issue_should_follow_when_needed
4015 def test_bulk_update_project_on_single_issue_should_follow_when_needed
4010 @request.session[:user_id] = 2
4016 @request.session[:user_id] = 2
4011 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
4017 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
4012 assert_redirected_to '/issues/1'
4018 assert_redirected_to '/issues/1'
4013 end
4019 end
4014
4020
4015 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
4021 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
4016 @request.session[:user_id] = 2
4022 @request.session[:user_id] = 2
4017 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
4023 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
4018 assert_redirected_to '/projects/onlinestore/issues'
4024 assert_redirected_to '/projects/onlinestore/issues'
4019 end
4025 end
4020
4026
4021 def test_bulk_update_tracker
4027 def test_bulk_update_tracker
4022 @request.session[:user_id] = 2
4028 @request.session[:user_id] = 2
4023 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
4029 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
4024 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4030 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4025 assert_equal 2, Issue.find(1).tracker_id
4031 assert_equal 2, Issue.find(1).tracker_id
4026 assert_equal 2, Issue.find(2).tracker_id
4032 assert_equal 2, Issue.find(2).tracker_id
4027 end
4033 end
4028
4034
4029 def test_bulk_update_status
4035 def test_bulk_update_status
4030 @request.session[:user_id] = 2
4036 @request.session[:user_id] = 2
4031 # update issues priority
4037 # update issues priority
4032 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
4038 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
4033 :issue => {:priority_id => '',
4039 :issue => {:priority_id => '',
4034 :assigned_to_id => '',
4040 :assigned_to_id => '',
4035 :status_id => '5'}
4041 :status_id => '5'}
4036
4042
4037 assert_response 302
4043 assert_response 302
4038 issue = Issue.find(1)
4044 issue = Issue.find(1)
4039 assert issue.closed?
4045 assert issue.closed?
4040 end
4046 end
4041
4047
4042 def test_bulk_update_priority
4048 def test_bulk_update_priority
4043 @request.session[:user_id] = 2
4049 @request.session[:user_id] = 2
4044 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
4050 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
4045
4051
4046 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4052 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4047 assert_equal 6, Issue.find(1).priority_id
4053 assert_equal 6, Issue.find(1).priority_id
4048 assert_equal 6, Issue.find(2).priority_id
4054 assert_equal 6, Issue.find(2).priority_id
4049 end
4055 end
4050
4056
4051 def test_bulk_update_with_notes
4057 def test_bulk_update_with_notes
4052 @request.session[:user_id] = 2
4058 @request.session[:user_id] = 2
4053 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
4059 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
4054
4060
4055 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4061 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4056 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
4062 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
4057 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
4063 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
4058 end
4064 end
4059
4065
4060 def test_bulk_update_parent_id
4066 def test_bulk_update_parent_id
4061 IssueRelation.delete_all
4067 IssueRelation.delete_all
4062 @request.session[:user_id] = 2
4068 @request.session[:user_id] = 2
4063 post :bulk_update, :ids => [1, 3],
4069 post :bulk_update, :ids => [1, 3],
4064 :notes => 'Bulk editing parent',
4070 :notes => 'Bulk editing parent',
4065 :issue => {:priority_id => '', :assigned_to_id => '',
4071 :issue => {:priority_id => '', :assigned_to_id => '',
4066 :status_id => '', :parent_issue_id => '2'}
4072 :status_id => '', :parent_issue_id => '2'}
4067 assert_response 302
4073 assert_response 302
4068 parent = Issue.find(2)
4074 parent = Issue.find(2)
4069 assert_equal parent.id, Issue.find(1).parent_id
4075 assert_equal parent.id, Issue.find(1).parent_id
4070 assert_equal parent.id, Issue.find(3).parent_id
4076 assert_equal parent.id, Issue.find(3).parent_id
4071 assert_equal [1, 3], parent.children.collect(&:id).sort
4077 assert_equal [1, 3], parent.children.collect(&:id).sort
4072 end
4078 end
4073
4079
4074 def test_bulk_update_estimated_hours
4080 def test_bulk_update_estimated_hours
4075 @request.session[:user_id] = 2
4081 @request.session[:user_id] = 2
4076 post :bulk_update, :ids => [1, 2], :issue => {:estimated_hours => 4.25}
4082 post :bulk_update, :ids => [1, 2], :issue => {:estimated_hours => 4.25}
4077
4083
4078 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4084 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4079 assert_equal 4.25, Issue.find(1).estimated_hours
4085 assert_equal 4.25, Issue.find(1).estimated_hours
4080 assert_equal 4.25, Issue.find(2).estimated_hours
4086 assert_equal 4.25, Issue.find(2).estimated_hours
4081 end
4087 end
4082
4088
4083 def test_bulk_update_custom_field
4089 def test_bulk_update_custom_field
4084 @request.session[:user_id] = 2
4090 @request.session[:user_id] = 2
4085 # update issues priority
4091 # update issues priority
4086 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
4092 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
4087 :issue => {:priority_id => '',
4093 :issue => {:priority_id => '',
4088 :assigned_to_id => '',
4094 :assigned_to_id => '',
4089 :custom_field_values => {'2' => '777'}}
4095 :custom_field_values => {'2' => '777'}}
4090
4096
4091 assert_response 302
4097 assert_response 302
4092
4098
4093 issue = Issue.find(1)
4099 issue = Issue.find(1)
4094 journal = issue.journals.reorder('created_on DESC').first
4100 journal = issue.journals.reorder('created_on DESC').first
4095 assert_equal '777', issue.custom_value_for(2).value
4101 assert_equal '777', issue.custom_value_for(2).value
4096 assert_equal 1, journal.details.size
4102 assert_equal 1, journal.details.size
4097 assert_equal '125', journal.details.first.old_value
4103 assert_equal '125', journal.details.first.old_value
4098 assert_equal '777', journal.details.first.value
4104 assert_equal '777', journal.details.first.value
4099 end
4105 end
4100
4106
4101 def test_bulk_update_custom_field_to_blank
4107 def test_bulk_update_custom_field_to_blank
4102 @request.session[:user_id] = 2
4108 @request.session[:user_id] = 2
4103 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
4109 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
4104 :issue => {:priority_id => '',
4110 :issue => {:priority_id => '',
4105 :assigned_to_id => '',
4111 :assigned_to_id => '',
4106 :custom_field_values => {'1' => '__none__'}}
4112 :custom_field_values => {'1' => '__none__'}}
4107 assert_response 302
4113 assert_response 302
4108 assert_equal '', Issue.find(1).custom_field_value(1)
4114 assert_equal '', Issue.find(1).custom_field_value(1)
4109 assert_equal '', Issue.find(3).custom_field_value(1)
4115 assert_equal '', Issue.find(3).custom_field_value(1)
4110 end
4116 end
4111
4117
4112 def test_bulk_update_multi_custom_field
4118 def test_bulk_update_multi_custom_field
4113 field = CustomField.find(1)
4119 field = CustomField.find(1)
4114 field.update_attribute :multiple, true
4120 field.update_attribute :multiple, true
4115
4121
4116 @request.session[:user_id] = 2
4122 @request.session[:user_id] = 2
4117 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
4123 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
4118 :issue => {:priority_id => '',
4124 :issue => {:priority_id => '',
4119 :assigned_to_id => '',
4125 :assigned_to_id => '',
4120 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
4126 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
4121
4127
4122 assert_response 302
4128 assert_response 302
4123
4129
4124 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
4130 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
4125 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
4131 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
4126 # the custom field is not associated with the issue tracker
4132 # the custom field is not associated with the issue tracker
4127 assert_nil Issue.find(2).custom_field_value(1)
4133 assert_nil Issue.find(2).custom_field_value(1)
4128 end
4134 end
4129
4135
4130 def test_bulk_update_multi_custom_field_to_blank
4136 def test_bulk_update_multi_custom_field_to_blank
4131 field = CustomField.find(1)
4137 field = CustomField.find(1)
4132 field.update_attribute :multiple, true
4138 field.update_attribute :multiple, true
4133
4139
4134 @request.session[:user_id] = 2
4140 @request.session[:user_id] = 2
4135 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
4141 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
4136 :issue => {:priority_id => '',
4142 :issue => {:priority_id => '',
4137 :assigned_to_id => '',
4143 :assigned_to_id => '',
4138 :custom_field_values => {'1' => ['__none__']}}
4144 :custom_field_values => {'1' => ['__none__']}}
4139 assert_response 302
4145 assert_response 302
4140 assert_equal [''], Issue.find(1).custom_field_value(1)
4146 assert_equal [''], Issue.find(1).custom_field_value(1)
4141 assert_equal [''], Issue.find(3).custom_field_value(1)
4147 assert_equal [''], Issue.find(3).custom_field_value(1)
4142 end
4148 end
4143
4149
4144 def test_bulk_update_unassign
4150 def test_bulk_update_unassign
4145 assert_not_nil Issue.find(2).assigned_to
4151 assert_not_nil Issue.find(2).assigned_to
4146 @request.session[:user_id] = 2
4152 @request.session[:user_id] = 2
4147 # unassign issues
4153 # unassign issues
4148 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
4154 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
4149 assert_response 302
4155 assert_response 302
4150 # check that the issues were updated
4156 # check that the issues were updated
4151 assert_nil Issue.find(2).assigned_to
4157 assert_nil Issue.find(2).assigned_to
4152 end
4158 end
4153
4159
4154 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
4160 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
4155 @request.session[:user_id] = 2
4161 @request.session[:user_id] = 2
4156
4162
4157 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
4163 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
4158
4164
4159 assert_response :redirect
4165 assert_response :redirect
4160 issues = Issue.find([1,2])
4166 issues = Issue.find([1,2])
4161 issues.each do |issue|
4167 issues.each do |issue|
4162 assert_equal 4, issue.fixed_version_id
4168 assert_equal 4, issue.fixed_version_id
4163 assert_not_equal issue.project_id, issue.fixed_version.project_id
4169 assert_not_equal issue.project_id, issue.fixed_version.project_id
4164 end
4170 end
4165 end
4171 end
4166
4172
4167 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
4173 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
4168 @request.session[:user_id] = 2
4174 @request.session[:user_id] = 2
4169 post :bulk_update, :ids => [1,2], :back_url => '/issues'
4175 post :bulk_update, :ids => [1,2], :back_url => '/issues'
4170
4176
4171 assert_response :redirect
4177 assert_response :redirect
4172 assert_redirected_to '/issues'
4178 assert_redirected_to '/issues'
4173 end
4179 end
4174
4180
4175 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
4181 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
4176 @request.session[:user_id] = 2
4182 @request.session[:user_id] = 2
4177 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
4183 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
4178
4184
4179 assert_response :redirect
4185 assert_response :redirect
4180 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
4186 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
4181 end
4187 end
4182
4188
4183 def test_bulk_update_with_all_failures_should_show_errors
4189 def test_bulk_update_with_all_failures_should_show_errors
4184 @request.session[:user_id] = 2
4190 @request.session[:user_id] = 2
4185 post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'}
4191 post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'}
4186
4192
4187 assert_response :success
4193 assert_response :success
4188 assert_template 'bulk_edit'
4194 assert_template 'bulk_edit'
4189 assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
4195 assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
4190 assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
4196 assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
4191
4197
4192 assert_equal [1, 2], assigns[:issues].map(&:id)
4198 assert_equal [1, 2], assigns[:issues].map(&:id)
4193 end
4199 end
4194
4200
4195 def test_bulk_update_with_some_failures_should_show_errors
4201 def test_bulk_update_with_some_failures_should_show_errors
4196 issue1 = Issue.generate!(:start_date => '2013-05-12')
4202 issue1 = Issue.generate!(:start_date => '2013-05-12')
4197 issue2 = Issue.generate!(:start_date => '2013-05-15')
4203 issue2 = Issue.generate!(:start_date => '2013-05-15')
4198 issue3 = Issue.generate!
4204 issue3 = Issue.generate!
4199 @request.session[:user_id] = 2
4205 @request.session[:user_id] = 2
4200 post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id],
4206 post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id],
4201 :issue => {:due_date => '2013-05-01'}
4207 :issue => {:due_date => '2013-05-01'}
4202 assert_response :success
4208 assert_response :success
4203 assert_template 'bulk_edit'
4209 assert_template 'bulk_edit'
4204 assert_select '#errorExplanation span',
4210 assert_select '#errorExplanation span',
4205 :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
4211 :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
4206 assert_select '#errorExplanation ul li',
4212 assert_select '#errorExplanation ul li',
4207 :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
4213 :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
4208 assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
4214 assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
4209 end
4215 end
4210
4216
4211 def test_bulk_update_with_failure_should_preserved_form_values
4217 def test_bulk_update_with_failure_should_preserved_form_values
4212 @request.session[:user_id] = 2
4218 @request.session[:user_id] = 2
4213 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2', :start_date => 'foo'}
4219 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2', :start_date => 'foo'}
4214
4220
4215 assert_response :success
4221 assert_response :success
4216 assert_template 'bulk_edit'
4222 assert_template 'bulk_edit'
4217 assert_select 'select[name=?]', 'issue[tracker_id]' do
4223 assert_select 'select[name=?]', 'issue[tracker_id]' do
4218 assert_select 'option[value="2"][selected=selected]'
4224 assert_select 'option[value="2"][selected=selected]'
4219 end
4225 end
4220 assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
4226 assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
4221 end
4227 end
4222
4228
4223 def test_get_bulk_copy
4229 def test_get_bulk_copy
4224 @request.session[:user_id] = 2
4230 @request.session[:user_id] = 2
4225 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4231 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4226 assert_response :success
4232 assert_response :success
4227 assert_template 'bulk_edit'
4233 assert_template 'bulk_edit'
4228
4234
4229 issues = assigns(:issues)
4235 issues = assigns(:issues)
4230 assert_not_nil issues
4236 assert_not_nil issues
4231 assert_equal [1, 2, 3], issues.map(&:id).sort
4237 assert_equal [1, 2, 3], issues.map(&:id).sort
4232
4238
4233 assert_select 'select[name=?]', 'issue[project_id]' do
4239 assert_select 'select[name=?]', 'issue[project_id]' do
4234 assert_select 'option[value=""]'
4240 assert_select 'option[value=""]'
4235 end
4241 end
4236 assert_select 'input[name=copy_attachments]'
4242 assert_select 'input[name=copy_attachments]'
4237 end
4243 end
4238
4244
4239 def test_get_bulk_copy_without_add_issues_permission_should_not_propose_current_project_as_target
4245 def test_get_bulk_copy_without_add_issues_permission_should_not_propose_current_project_as_target
4240 user = setup_user_with_copy_but_not_add_permission
4246 user = setup_user_with_copy_but_not_add_permission
4241 @request.session[:user_id] = user.id
4247 @request.session[:user_id] = user.id
4242
4248
4243 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4249 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4244 assert_response :success
4250 assert_response :success
4245 assert_template 'bulk_edit'
4251 assert_template 'bulk_edit'
4246
4252
4247 assert_select 'select[name=?]', 'issue[project_id]' do
4253 assert_select 'select[name=?]', 'issue[project_id]' do
4248 assert_select 'option[value=""]', 0
4254 assert_select 'option[value=""]', 0
4249 assert_select 'option[value="2"]'
4255 assert_select 'option[value="2"]'
4250 end
4256 end
4251 end
4257 end
4252
4258
4253 def test_bulk_copy_to_another_project
4259 def test_bulk_copy_to_another_project
4254 @request.session[:user_id] = 2
4260 @request.session[:user_id] = 2
4255 assert_difference 'Issue.count', 2 do
4261 assert_difference 'Issue.count', 2 do
4256 assert_no_difference 'Project.find(1).issues.count' do
4262 assert_no_difference 'Project.find(1).issues.count' do
4257 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
4263 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
4258 end
4264 end
4259 end
4265 end
4260 assert_redirected_to '/projects/ecookbook/issues'
4266 assert_redirected_to '/projects/ecookbook/issues'
4261
4267
4262 copies = Issue.order('id DESC').limit(issues.size)
4268 copies = Issue.order('id DESC').limit(issues.size)
4263 copies.each do |copy|
4269 copies.each do |copy|
4264 assert_equal 2, copy.project_id
4270 assert_equal 2, copy.project_id
4265 end
4271 end
4266 end
4272 end
4267
4273
4268 def test_bulk_copy_without_add_issues_permission_should_be_allowed_on_project_with_permission
4274 def test_bulk_copy_without_add_issues_permission_should_be_allowed_on_project_with_permission
4269 user = setup_user_with_copy_but_not_add_permission
4275 user = setup_user_with_copy_but_not_add_permission
4270 @request.session[:user_id] = user.id
4276 @request.session[:user_id] = user.id
4271
4277
4272 assert_difference 'Issue.count', 3 do
4278 assert_difference 'Issue.count', 3 do
4273 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '2'}, :copy => '1'
4279 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '2'}, :copy => '1'
4274 assert_response 302
4280 assert_response 302
4275 end
4281 end
4276 end
4282 end
4277
4283
4278 def test_bulk_copy_on_same_project_without_add_issues_permission_should_be_denied
4284 def test_bulk_copy_on_same_project_without_add_issues_permission_should_be_denied
4279 user = setup_user_with_copy_but_not_add_permission
4285 user = setup_user_with_copy_but_not_add_permission
4280 @request.session[:user_id] = user.id
4286 @request.session[:user_id] = user.id
4281
4287
4282 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => ''}, :copy => '1'
4288 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => ''}, :copy => '1'
4283 assert_response 403
4289 assert_response 403
4284 end
4290 end
4285
4291
4286 def test_bulk_copy_on_different_project_without_add_issues_permission_should_be_denied
4292 def test_bulk_copy_on_different_project_without_add_issues_permission_should_be_denied
4287 user = setup_user_with_copy_but_not_add_permission
4293 user = setup_user_with_copy_but_not_add_permission
4288 @request.session[:user_id] = user.id
4294 @request.session[:user_id] = user.id
4289
4295
4290 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '1'}, :copy => '1'
4296 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '1'}, :copy => '1'
4291 assert_response 403
4297 assert_response 403
4292 end
4298 end
4293
4299
4294 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
4300 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
4295 @request.session[:user_id] = 2
4301 @request.session[:user_id] = 2
4296 issues = [
4302 issues = [
4297 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
4303 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
4298 :priority_id => 2, :subject => 'issue 1', :author_id => 1,
4304 :priority_id => 2, :subject => 'issue 1', :author_id => 1,
4299 :assigned_to_id => nil),
4305 :assigned_to_id => nil),
4300 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2,
4306 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2,
4301 :priority_id => 1, :subject => 'issue 2', :author_id => 2,
4307 :priority_id => 1, :subject => 'issue 2', :author_id => 2,
4302 :assigned_to_id => 3)
4308 :assigned_to_id => 3)
4303 ]
4309 ]
4304 assert_difference 'Issue.count', issues.size do
4310 assert_difference 'Issue.count', issues.size do
4305 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
4311 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
4306 :issue => {
4312 :issue => {
4307 :project_id => '', :tracker_id => '', :assigned_to_id => '',
4313 :project_id => '', :tracker_id => '', :assigned_to_id => '',
4308 :status_id => '', :start_date => '', :due_date => ''
4314 :status_id => '', :start_date => '', :due_date => ''
4309 }
4315 }
4310 end
4316 end
4311
4317
4312 copies = Issue.order('id DESC').limit(issues.size)
4318 copies = Issue.order('id DESC').limit(issues.size)
4313 issues.each do |orig|
4319 issues.each do |orig|
4314 copy = copies.detect {|c| c.subject == orig.subject}
4320 copy = copies.detect {|c| c.subject == orig.subject}
4315 assert_not_nil copy
4321 assert_not_nil copy
4316 assert_equal orig.project_id, copy.project_id
4322 assert_equal orig.project_id, copy.project_id
4317 assert_equal orig.tracker_id, copy.tracker_id
4323 assert_equal orig.tracker_id, copy.tracker_id
4318 assert_equal orig.status_id, copy.status_id
4324 assert_equal orig.status_id, copy.status_id
4319 assert_equal orig.assigned_to_id, copy.assigned_to_id
4325 assert_equal orig.assigned_to_id, copy.assigned_to_id
4320 assert_equal orig.priority_id, copy.priority_id
4326 assert_equal orig.priority_id, copy.priority_id
4321 end
4327 end
4322 end
4328 end
4323
4329
4324 def test_bulk_copy_should_allow_changing_the_issue_attributes
4330 def test_bulk_copy_should_allow_changing_the_issue_attributes
4325 # Fixes random test failure with Mysql
4331 # Fixes random test failure with Mysql
4326 # where Issue.where(:project_id => 2).limit(2).order('id desc')
4332 # where Issue.where(:project_id => 2).limit(2).order('id desc')
4327 # doesn't return the expected results
4333 # doesn't return the expected results
4328 Issue.delete_all("project_id=2")
4334 Issue.delete_all("project_id=2")
4329
4335
4330 @request.session[:user_id] = 2
4336 @request.session[:user_id] = 2
4331 assert_difference 'Issue.count', 2 do
4337 assert_difference 'Issue.count', 2 do
4332 assert_no_difference 'Project.find(1).issues.count' do
4338 assert_no_difference 'Project.find(1).issues.count' do
4333 post :bulk_update, :ids => [1, 2], :copy => '1',
4339 post :bulk_update, :ids => [1, 2], :copy => '1',
4334 :issue => {
4340 :issue => {
4335 :project_id => '2', :tracker_id => '', :assigned_to_id => '2',
4341 :project_id => '2', :tracker_id => '', :assigned_to_id => '2',
4336 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
4342 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
4337 }
4343 }
4338 end
4344 end
4339 end
4345 end
4340
4346
4341 copied_issues = Issue.where(:project_id => 2).limit(2).order('id desc').to_a
4347 copied_issues = Issue.where(:project_id => 2).limit(2).order('id desc').to_a
4342 assert_equal 2, copied_issues.size
4348 assert_equal 2, copied_issues.size
4343 copied_issues.each do |issue|
4349 copied_issues.each do |issue|
4344 assert_equal 2, issue.project_id, "Project is incorrect"
4350 assert_equal 2, issue.project_id, "Project is incorrect"
4345 assert_equal 2, issue.assigned_to_id, "Assigned to is incorrect"
4351 assert_equal 2, issue.assigned_to_id, "Assigned to is incorrect"
4346 assert_equal 1, issue.status_id, "Status is incorrect"
4352 assert_equal 1, issue.status_id, "Status is incorrect"
4347 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
4353 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
4348 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
4354 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
4349 end
4355 end
4350 end
4356 end
4351
4357
4352 def test_bulk_copy_should_allow_adding_a_note
4358 def test_bulk_copy_should_allow_adding_a_note
4353 @request.session[:user_id] = 2
4359 @request.session[:user_id] = 2
4354 assert_difference 'Issue.count', 1 do
4360 assert_difference 'Issue.count', 1 do
4355 post :bulk_update, :ids => [1], :copy => '1',
4361 post :bulk_update, :ids => [1], :copy => '1',
4356 :notes => 'Copying one issue',
4362 :notes => 'Copying one issue',
4357 :issue => {
4363 :issue => {
4358 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
4364 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
4359 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
4365 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
4360 }
4366 }
4361 end
4367 end
4362 issue = Issue.order('id DESC').first
4368 issue = Issue.order('id DESC').first
4363 assert_equal 1, issue.journals.size
4369 assert_equal 1, issue.journals.size
4364 journal = issue.journals.first
4370 journal = issue.journals.first
4365 assert_equal 'Copying one issue', journal.notes
4371 assert_equal 'Copying one issue', journal.notes
4366 end
4372 end
4367
4373
4368 def test_bulk_copy_should_allow_not_copying_the_attachments
4374 def test_bulk_copy_should_allow_not_copying_the_attachments
4369 attachment_count = Issue.find(3).attachments.size
4375 attachment_count = Issue.find(3).attachments.size
4370 assert attachment_count > 0
4376 assert attachment_count > 0
4371 @request.session[:user_id] = 2
4377 @request.session[:user_id] = 2
4372
4378
4373 assert_difference 'Issue.count', 1 do
4379 assert_difference 'Issue.count', 1 do
4374 assert_no_difference 'Attachment.count' do
4380 assert_no_difference 'Attachment.count' do
4375 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '0',
4381 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '0',
4376 :issue => {
4382 :issue => {
4377 :project_id => ''
4383 :project_id => ''
4378 }
4384 }
4379 end
4385 end
4380 end
4386 end
4381 end
4387 end
4382
4388
4383 def test_bulk_copy_should_allow_copying_the_attachments
4389 def test_bulk_copy_should_allow_copying_the_attachments
4384 attachment_count = Issue.find(3).attachments.size
4390 attachment_count = Issue.find(3).attachments.size
4385 assert attachment_count > 0
4391 assert attachment_count > 0
4386 @request.session[:user_id] = 2
4392 @request.session[:user_id] = 2
4387
4393
4388 assert_difference 'Issue.count', 1 do
4394 assert_difference 'Issue.count', 1 do
4389 assert_difference 'Attachment.count', attachment_count do
4395 assert_difference 'Attachment.count', attachment_count do
4390 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
4396 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
4391 :issue => {
4397 :issue => {
4392 :project_id => ''
4398 :project_id => ''
4393 }
4399 }
4394 end
4400 end
4395 end
4401 end
4396 end
4402 end
4397
4403
4398 def test_bulk_copy_should_add_relations_with_copied_issues
4404 def test_bulk_copy_should_add_relations_with_copied_issues
4399 @request.session[:user_id] = 2
4405 @request.session[:user_id] = 2
4400
4406
4401 assert_difference 'Issue.count', 2 do
4407 assert_difference 'Issue.count', 2 do
4402 assert_difference 'IssueRelation.count', 2 do
4408 assert_difference 'IssueRelation.count', 2 do
4403 post :bulk_update, :ids => [1, 3], :copy => '1', :link_copy => '1',
4409 post :bulk_update, :ids => [1, 3], :copy => '1', :link_copy => '1',
4404 :issue => {
4410 :issue => {
4405 :project_id => '1'
4411 :project_id => '1'
4406 }
4412 }
4407 end
4413 end
4408 end
4414 end
4409 end
4415 end
4410
4416
4411 def test_bulk_copy_should_allow_not_copying_the_subtasks
4417 def test_bulk_copy_should_allow_not_copying_the_subtasks
4412 issue = Issue.generate_with_descendants!
4418 issue = Issue.generate_with_descendants!
4413 @request.session[:user_id] = 2
4419 @request.session[:user_id] = 2
4414
4420
4415 assert_difference 'Issue.count', 1 do
4421 assert_difference 'Issue.count', 1 do
4416 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '0',
4422 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '0',
4417 :issue => {
4423 :issue => {
4418 :project_id => ''
4424 :project_id => ''
4419 }
4425 }
4420 end
4426 end
4421 end
4427 end
4422
4428
4423 def test_bulk_copy_should_allow_copying_the_subtasks
4429 def test_bulk_copy_should_allow_copying_the_subtasks
4424 issue = Issue.generate_with_descendants!
4430 issue = Issue.generate_with_descendants!
4425 count = issue.descendants.count
4431 count = issue.descendants.count
4426 @request.session[:user_id] = 2
4432 @request.session[:user_id] = 2
4427
4433
4428 assert_difference 'Issue.count', count+1 do
4434 assert_difference 'Issue.count', count+1 do
4429 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
4435 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
4430 :issue => {
4436 :issue => {
4431 :project_id => ''
4437 :project_id => ''
4432 }
4438 }
4433 end
4439 end
4434 copy = Issue.where(:parent_id => nil).order("id DESC").first
4440 copy = Issue.where(:parent_id => nil).order("id DESC").first
4435 assert_equal count, copy.descendants.count
4441 assert_equal count, copy.descendants.count
4436 end
4442 end
4437
4443
4438 def test_bulk_copy_should_not_copy_selected_subtasks_twice
4444 def test_bulk_copy_should_not_copy_selected_subtasks_twice
4439 issue = Issue.generate_with_descendants!
4445 issue = Issue.generate_with_descendants!
4440 count = issue.descendants.count
4446 count = issue.descendants.count
4441 @request.session[:user_id] = 2
4447 @request.session[:user_id] = 2
4442
4448
4443 assert_difference 'Issue.count', count+1 do
4449 assert_difference 'Issue.count', count+1 do
4444 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
4450 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
4445 :issue => {
4451 :issue => {
4446 :project_id => ''
4452 :project_id => ''
4447 }
4453 }
4448 end
4454 end
4449 copy = Issue.where(:parent_id => nil).order("id DESC").first
4455 copy = Issue.where(:parent_id => nil).order("id DESC").first
4450 assert_equal count, copy.descendants.count
4456 assert_equal count, copy.descendants.count
4451 end
4457 end
4452
4458
4453 def test_bulk_copy_to_another_project_should_follow_when_needed
4459 def test_bulk_copy_to_another_project_should_follow_when_needed
4454 @request.session[:user_id] = 2
4460 @request.session[:user_id] = 2
4455 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
4461 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
4456 issue = Issue.order('id DESC').first
4462 issue = Issue.order('id DESC').first
4457 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
4463 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
4458 end
4464 end
4459
4465
4460 def test_bulk_copy_with_all_failures_should_display_errors
4466 def test_bulk_copy_with_all_failures_should_display_errors
4461 @request.session[:user_id] = 2
4467 @request.session[:user_id] = 2
4462 post :bulk_update, :ids => [1, 2], :copy => '1', :issue => {:start_date => 'foo'}
4468 post :bulk_update, :ids => [1, 2], :copy => '1', :issue => {:start_date => 'foo'}
4463
4469
4464 assert_response :success
4470 assert_response :success
4465 end
4471 end
4466
4472
4467 def test_destroy_issue_with_no_time_entries
4473 def test_destroy_issue_with_no_time_entries
4468 assert_nil TimeEntry.find_by_issue_id(2)
4474 assert_nil TimeEntry.find_by_issue_id(2)
4469 @request.session[:user_id] = 2
4475 @request.session[:user_id] = 2
4470
4476
4471 assert_difference 'Issue.count', -1 do
4477 assert_difference 'Issue.count', -1 do
4472 delete :destroy, :id => 2
4478 delete :destroy, :id => 2
4473 end
4479 end
4474 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4480 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4475 assert_nil Issue.find_by_id(2)
4481 assert_nil Issue.find_by_id(2)
4476 end
4482 end
4477
4483
4478 def test_destroy_issues_with_time_entries
4484 def test_destroy_issues_with_time_entries
4479 @request.session[:user_id] = 2
4485 @request.session[:user_id] = 2
4480
4486
4481 assert_no_difference 'Issue.count' do
4487 assert_no_difference 'Issue.count' do
4482 delete :destroy, :ids => [1, 3]
4488 delete :destroy, :ids => [1, 3]
4483 end
4489 end
4484 assert_response :success
4490 assert_response :success
4485 assert_template 'destroy'
4491 assert_template 'destroy'
4486 assert_not_nil assigns(:hours)
4492 assert_not_nil assigns(:hours)
4487 assert Issue.find_by_id(1) && Issue.find_by_id(3)
4493 assert Issue.find_by_id(1) && Issue.find_by_id(3)
4488
4494
4489 assert_select 'form' do
4495 assert_select 'form' do
4490 assert_select 'input[name=_method][value=delete]'
4496 assert_select 'input[name=_method][value=delete]'
4491 end
4497 end
4492 end
4498 end
4493
4499
4494 def test_destroy_issues_and_destroy_time_entries
4500 def test_destroy_issues_and_destroy_time_entries
4495 @request.session[:user_id] = 2
4501 @request.session[:user_id] = 2
4496
4502
4497 assert_difference 'Issue.count', -2 do
4503 assert_difference 'Issue.count', -2 do
4498 assert_difference 'TimeEntry.count', -3 do
4504 assert_difference 'TimeEntry.count', -3 do
4499 delete :destroy, :ids => [1, 3], :todo => 'destroy'
4505 delete :destroy, :ids => [1, 3], :todo => 'destroy'
4500 end
4506 end
4501 end
4507 end
4502 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4508 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4503 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4509 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4504 assert_nil TimeEntry.find_by_id([1, 2])
4510 assert_nil TimeEntry.find_by_id([1, 2])
4505 end
4511 end
4506
4512
4507 def test_destroy_issues_and_assign_time_entries_to_project
4513 def test_destroy_issues_and_assign_time_entries_to_project
4508 @request.session[:user_id] = 2
4514 @request.session[:user_id] = 2
4509
4515
4510 assert_difference 'Issue.count', -2 do
4516 assert_difference 'Issue.count', -2 do
4511 assert_no_difference 'TimeEntry.count' do
4517 assert_no_difference 'TimeEntry.count' do
4512 delete :destroy, :ids => [1, 3], :todo => 'nullify'
4518 delete :destroy, :ids => [1, 3], :todo => 'nullify'
4513 end
4519 end
4514 end
4520 end
4515 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4521 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4516 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4522 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4517 assert_nil TimeEntry.find(1).issue_id
4523 assert_nil TimeEntry.find(1).issue_id
4518 assert_nil TimeEntry.find(2).issue_id
4524 assert_nil TimeEntry.find(2).issue_id
4519 end
4525 end
4520
4526
4521 def test_destroy_issues_and_reassign_time_entries_to_another_issue
4527 def test_destroy_issues_and_reassign_time_entries_to_another_issue
4522 @request.session[:user_id] = 2
4528 @request.session[:user_id] = 2
4523
4529
4524 assert_difference 'Issue.count', -2 do
4530 assert_difference 'Issue.count', -2 do
4525 assert_no_difference 'TimeEntry.count' do
4531 assert_no_difference 'TimeEntry.count' do
4526 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
4532 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
4527 end
4533 end
4528 end
4534 end
4529 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4535 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4530 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4536 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4531 assert_equal 2, TimeEntry.find(1).issue_id
4537 assert_equal 2, TimeEntry.find(1).issue_id
4532 assert_equal 2, TimeEntry.find(2).issue_id
4538 assert_equal 2, TimeEntry.find(2).issue_id
4533 end
4539 end
4534
4540
4535 def test_destroy_issues_and_reassign_time_entries_to_an_invalid_issue_should_fail
4541 def test_destroy_issues_and_reassign_time_entries_to_an_invalid_issue_should_fail
4536 @request.session[:user_id] = 2
4542 @request.session[:user_id] = 2
4537
4543
4538 assert_no_difference 'Issue.count' do
4544 assert_no_difference 'Issue.count' do
4539 assert_no_difference 'TimeEntry.count' do
4545 assert_no_difference 'TimeEntry.count' do
4540 # try to reassign time to an issue of another project
4546 # try to reassign time to an issue of another project
4541 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 4
4547 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 4
4542 end
4548 end
4543 end
4549 end
4544 assert_response :success
4550 assert_response :success
4545 assert_template 'destroy'
4551 assert_template 'destroy'
4546 end
4552 end
4547
4553
4548 def test_destroy_issues_from_different_projects
4554 def test_destroy_issues_from_different_projects
4549 @request.session[:user_id] = 2
4555 @request.session[:user_id] = 2
4550
4556
4551 assert_difference 'Issue.count', -3 do
4557 assert_difference 'Issue.count', -3 do
4552 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
4558 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
4553 end
4559 end
4554 assert_redirected_to :controller => 'issues', :action => 'index'
4560 assert_redirected_to :controller => 'issues', :action => 'index'
4555 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
4561 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
4556 end
4562 end
4557
4563
4558 def test_destroy_parent_and_child_issues
4564 def test_destroy_parent_and_child_issues
4559 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
4565 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
4560 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
4566 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
4561 assert child.is_descendant_of?(parent.reload)
4567 assert child.is_descendant_of?(parent.reload)
4562
4568
4563 @request.session[:user_id] = 2
4569 @request.session[:user_id] = 2
4564 assert_difference 'Issue.count', -2 do
4570 assert_difference 'Issue.count', -2 do
4565 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
4571 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
4566 end
4572 end
4567 assert_response 302
4573 assert_response 302
4568 end
4574 end
4569
4575
4570 def test_destroy_invalid_should_respond_with_404
4576 def test_destroy_invalid_should_respond_with_404
4571 @request.session[:user_id] = 2
4577 @request.session[:user_id] = 2
4572 assert_no_difference 'Issue.count' do
4578 assert_no_difference 'Issue.count' do
4573 delete :destroy, :id => 999
4579 delete :destroy, :id => 999
4574 end
4580 end
4575 assert_response 404
4581 assert_response 404
4576 end
4582 end
4577
4583
4578 def test_default_search_scope
4584 def test_default_search_scope
4579 get :index
4585 get :index
4580
4586
4581 assert_select 'div#quick-search form' do
4587 assert_select 'div#quick-search form' do
4582 assert_select 'input[name=issues][value="1"][type=hidden]'
4588 assert_select 'input[name=issues][value="1"][type=hidden]'
4583 end
4589 end
4584 end
4590 end
4585
4591
4586 def setup_user_with_copy_but_not_add_permission
4592 def setup_user_with_copy_but_not_add_permission
4587 Role.all.each {|r| r.remove_permission! :add_issues}
4593 Role.all.each {|r| r.remove_permission! :add_issues}
4588 Role.find_by_name('Manager').add_permission! :add_issues
4594 Role.find_by_name('Manager').add_permission! :add_issues
4589 user = User.generate!
4595 user = User.generate!
4590 User.add_to_project(user, Project.find(1), Role.find_by_name('Developer'))
4596 User.add_to_project(user, Project.find(1), Role.find_by_name('Developer'))
4591 User.add_to_project(user, Project.find(2), Role.find_by_name('Manager'))
4597 User.add_to_project(user, Project.find(2), Role.find_by_name('Manager'))
4592 user
4598 user
4593 end
4599 end
4594 end
4600 end
General Comments 0
You need to be logged in to leave comments. Login now