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