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