##// END OF EJS Templates
code layout clean up of test_all_dependent_issues at test/unit/issue_test.rb...
Toshi MARUYAMA -
r7358:1d4cf3ecb687
parent child
Show More
@@ -1,1095 +1,1101
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class IssueTest < ActiveSupport::TestCase
20 class IssueTest < ActiveSupport::TestCase
21 fixtures :projects, :users, :members, :member_roles, :roles,
21 fixtures :projects, :users, :members, :member_roles, :roles,
22 :trackers, :projects_trackers,
22 :trackers, :projects_trackers,
23 :enabled_modules,
23 :enabled_modules,
24 :versions,
24 :versions,
25 :issue_statuses, :issue_categories, :issue_relations, :workflows,
25 :issue_statuses, :issue_categories, :issue_relations, :workflows,
26 :enumerations,
26 :enumerations,
27 :issues,
27 :issues,
28 :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
28 :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
29 :time_entries
29 :time_entries
30
30
31 def test_create
31 def test_create
32 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
32 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
33 :status_id => 1, :priority => IssuePriority.all.first,
33 :status_id => 1, :priority => IssuePriority.all.first,
34 :subject => 'test_create',
34 :subject => 'test_create',
35 :description => 'IssueTest#test_create', :estimated_hours => '1:30')
35 :description => 'IssueTest#test_create', :estimated_hours => '1:30')
36 assert issue.save
36 assert issue.save
37 issue.reload
37 issue.reload
38 assert_equal 1.5, issue.estimated_hours
38 assert_equal 1.5, issue.estimated_hours
39 end
39 end
40
40
41 def test_create_minimal
41 def test_create_minimal
42 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
42 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
43 :status_id => 1, :priority => IssuePriority.all.first,
43 :status_id => 1, :priority => IssuePriority.all.first,
44 :subject => 'test_create')
44 :subject => 'test_create')
45 assert issue.save
45 assert issue.save
46 assert issue.description.nil?
46 assert issue.description.nil?
47 end
47 end
48
48
49 def test_create_with_required_custom_field
49 def test_create_with_required_custom_field
50 field = IssueCustomField.find_by_name('Database')
50 field = IssueCustomField.find_by_name('Database')
51 field.update_attribute(:is_required, true)
51 field.update_attribute(:is_required, true)
52
52
53 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
53 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
54 :status_id => 1, :subject => 'test_create',
54 :status_id => 1, :subject => 'test_create',
55 :description => 'IssueTest#test_create_with_required_custom_field')
55 :description => 'IssueTest#test_create_with_required_custom_field')
56 assert issue.available_custom_fields.include?(field)
56 assert issue.available_custom_fields.include?(field)
57 # No value for the custom field
57 # No value for the custom field
58 assert !issue.save
58 assert !issue.save
59 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
59 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
60 # Blank value
60 # Blank value
61 issue.custom_field_values = { field.id => '' }
61 issue.custom_field_values = { field.id => '' }
62 assert !issue.save
62 assert !issue.save
63 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
63 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
64 # Invalid value
64 # Invalid value
65 issue.custom_field_values = { field.id => 'SQLServer' }
65 issue.custom_field_values = { field.id => 'SQLServer' }
66 assert !issue.save
66 assert !issue.save
67 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
67 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
68 # Valid value
68 # Valid value
69 issue.custom_field_values = { field.id => 'PostgreSQL' }
69 issue.custom_field_values = { field.id => 'PostgreSQL' }
70 assert issue.save
70 assert issue.save
71 issue.reload
71 issue.reload
72 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
72 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
73 end
73 end
74
74
75 def test_create_with_group_assignment
75 def test_create_with_group_assignment
76 with_settings :issue_group_assignment => '1' do
76 with_settings :issue_group_assignment => '1' do
77 assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
77 assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
78 :subject => 'Group assignment',
78 :subject => 'Group assignment',
79 :assigned_to_id => 11).save
79 :assigned_to_id => 11).save
80 issue = Issue.first(:order => 'id DESC')
80 issue = Issue.first(:order => 'id DESC')
81 assert_kind_of Group, issue.assigned_to
81 assert_kind_of Group, issue.assigned_to
82 assert_equal Group.find(11), issue.assigned_to
82 assert_equal Group.find(11), issue.assigned_to
83 end
83 end
84 end
84 end
85
85
86 def assert_visibility_match(user, issues)
86 def assert_visibility_match(user, issues)
87 assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
87 assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
88 end
88 end
89
89
90 def test_visible_scope_for_anonymous
90 def test_visible_scope_for_anonymous
91 # Anonymous user should see issues of public projects only
91 # Anonymous user should see issues of public projects only
92 issues = Issue.visible(User.anonymous).all
92 issues = Issue.visible(User.anonymous).all
93 assert issues.any?
93 assert issues.any?
94 assert_nil issues.detect {|issue| !issue.project.is_public?}
94 assert_nil issues.detect {|issue| !issue.project.is_public?}
95 assert_nil issues.detect {|issue| issue.is_private?}
95 assert_nil issues.detect {|issue| issue.is_private?}
96 assert_visibility_match User.anonymous, issues
96 assert_visibility_match User.anonymous, issues
97 end
97 end
98
98
99 def test_visible_scope_for_anonymous_with_own_issues_visibility
99 def test_visible_scope_for_anonymous_with_own_issues_visibility
100 Role.anonymous.update_attribute :issues_visibility, 'own'
100 Role.anonymous.update_attribute :issues_visibility, 'own'
101 Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => User.anonymous.id, :subject => 'Issue by anonymous')
101 Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => User.anonymous.id, :subject => 'Issue by anonymous')
102
102
103 issues = Issue.visible(User.anonymous).all
103 issues = Issue.visible(User.anonymous).all
104 assert issues.any?
104 assert issues.any?
105 assert_nil issues.detect {|issue| issue.author != User.anonymous}
105 assert_nil issues.detect {|issue| issue.author != User.anonymous}
106 assert_visibility_match User.anonymous, issues
106 assert_visibility_match User.anonymous, issues
107 end
107 end
108
108
109 def test_visible_scope_for_anonymous_without_view_issues_permissions
109 def test_visible_scope_for_anonymous_without_view_issues_permissions
110 # Anonymous user should not see issues without permission
110 # Anonymous user should not see issues without permission
111 Role.anonymous.remove_permission!(:view_issues)
111 Role.anonymous.remove_permission!(:view_issues)
112 issues = Issue.visible(User.anonymous).all
112 issues = Issue.visible(User.anonymous).all
113 assert issues.empty?
113 assert issues.empty?
114 assert_visibility_match User.anonymous, issues
114 assert_visibility_match User.anonymous, issues
115 end
115 end
116
116
117 def test_visible_scope_for_non_member
117 def test_visible_scope_for_non_member
118 user = User.find(9)
118 user = User.find(9)
119 assert user.projects.empty?
119 assert user.projects.empty?
120 # Non member user should see issues of public projects only
120 # Non member user should see issues of public projects only
121 issues = Issue.visible(user).all
121 issues = Issue.visible(user).all
122 assert issues.any?
122 assert issues.any?
123 assert_nil issues.detect {|issue| !issue.project.is_public?}
123 assert_nil issues.detect {|issue| !issue.project.is_public?}
124 assert_nil issues.detect {|issue| issue.is_private?}
124 assert_nil issues.detect {|issue| issue.is_private?}
125 assert_visibility_match user, issues
125 assert_visibility_match user, issues
126 end
126 end
127
127
128 def test_visible_scope_for_non_member_with_own_issues_visibility
128 def test_visible_scope_for_non_member_with_own_issues_visibility
129 Role.non_member.update_attribute :issues_visibility, 'own'
129 Role.non_member.update_attribute :issues_visibility, 'own'
130 Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member')
130 Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member')
131 user = User.find(9)
131 user = User.find(9)
132
132
133 issues = Issue.visible(user).all
133 issues = Issue.visible(user).all
134 assert issues.any?
134 assert issues.any?
135 assert_nil issues.detect {|issue| issue.author != user}
135 assert_nil issues.detect {|issue| issue.author != user}
136 assert_visibility_match user, issues
136 assert_visibility_match user, issues
137 end
137 end
138
138
139 def test_visible_scope_for_non_member_without_view_issues_permissions
139 def test_visible_scope_for_non_member_without_view_issues_permissions
140 # Non member user should not see issues without permission
140 # Non member user should not see issues without permission
141 Role.non_member.remove_permission!(:view_issues)
141 Role.non_member.remove_permission!(:view_issues)
142 user = User.find(9)
142 user = User.find(9)
143 assert user.projects.empty?
143 assert user.projects.empty?
144 issues = Issue.visible(user).all
144 issues = Issue.visible(user).all
145 assert issues.empty?
145 assert issues.empty?
146 assert_visibility_match user, issues
146 assert_visibility_match user, issues
147 end
147 end
148
148
149 def test_visible_scope_for_member
149 def test_visible_scope_for_member
150 user = User.find(9)
150 user = User.find(9)
151 # User should see issues of projects for which he has view_issues permissions only
151 # User should see issues of projects for which he has view_issues permissions only
152 Role.non_member.remove_permission!(:view_issues)
152 Role.non_member.remove_permission!(:view_issues)
153 Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
153 Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
154 issues = Issue.visible(user).all
154 issues = Issue.visible(user).all
155 assert issues.any?
155 assert issues.any?
156 assert_nil issues.detect {|issue| issue.project_id != 3}
156 assert_nil issues.detect {|issue| issue.project_id != 3}
157 assert_nil issues.detect {|issue| issue.is_private?}
157 assert_nil issues.detect {|issue| issue.is_private?}
158 assert_visibility_match user, issues
158 assert_visibility_match user, issues
159 end
159 end
160
160
161 def test_visible_scope_for_admin
161 def test_visible_scope_for_admin
162 user = User.find(1)
162 user = User.find(1)
163 user.members.each(&:destroy)
163 user.members.each(&:destroy)
164 assert user.projects.empty?
164 assert user.projects.empty?
165 issues = Issue.visible(user).all
165 issues = Issue.visible(user).all
166 assert issues.any?
166 assert issues.any?
167 # Admin should see issues on private projects that he does not belong to
167 # Admin should see issues on private projects that he does not belong to
168 assert issues.detect {|issue| !issue.project.is_public?}
168 assert issues.detect {|issue| !issue.project.is_public?}
169 # Admin should see private issues of other users
169 # Admin should see private issues of other users
170 assert issues.detect {|issue| issue.is_private? && issue.author != user}
170 assert issues.detect {|issue| issue.is_private? && issue.author != user}
171 assert_visibility_match user, issues
171 assert_visibility_match user, issues
172 end
172 end
173
173
174 def test_visible_scope_with_project
174 def test_visible_scope_with_project
175 project = Project.find(1)
175 project = Project.find(1)
176 issues = Issue.visible(User.find(2), :project => project).all
176 issues = Issue.visible(User.find(2), :project => project).all
177 projects = issues.collect(&:project).uniq
177 projects = issues.collect(&:project).uniq
178 assert_equal 1, projects.size
178 assert_equal 1, projects.size
179 assert_equal project, projects.first
179 assert_equal project, projects.first
180 end
180 end
181
181
182 def test_visible_scope_with_project_and_subprojects
182 def test_visible_scope_with_project_and_subprojects
183 project = Project.find(1)
183 project = Project.find(1)
184 issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
184 issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
185 projects = issues.collect(&:project).uniq
185 projects = issues.collect(&:project).uniq
186 assert projects.size > 1
186 assert projects.size > 1
187 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
187 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
188 end
188 end
189
189
190 def test_visible_and_nested_set_scopes
190 def test_visible_and_nested_set_scopes
191 assert_equal 0, Issue.find(1).descendants.visible.all.size
191 assert_equal 0, Issue.find(1).descendants.visible.all.size
192 end
192 end
193
193
194 def test_errors_full_messages_should_include_custom_fields_errors
194 def test_errors_full_messages_should_include_custom_fields_errors
195 field = IssueCustomField.find_by_name('Database')
195 field = IssueCustomField.find_by_name('Database')
196
196
197 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
197 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
198 :status_id => 1, :subject => 'test_create',
198 :status_id => 1, :subject => 'test_create',
199 :description => 'IssueTest#test_create_with_required_custom_field')
199 :description => 'IssueTest#test_create_with_required_custom_field')
200 assert issue.available_custom_fields.include?(field)
200 assert issue.available_custom_fields.include?(field)
201 # Invalid value
201 # Invalid value
202 issue.custom_field_values = { field.id => 'SQLServer' }
202 issue.custom_field_values = { field.id => 'SQLServer' }
203
203
204 assert !issue.valid?
204 assert !issue.valid?
205 assert_equal 1, issue.errors.full_messages.size
205 assert_equal 1, issue.errors.full_messages.size
206 assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}", issue.errors.full_messages.first
206 assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}", issue.errors.full_messages.first
207 end
207 end
208
208
209 def test_update_issue_with_required_custom_field
209 def test_update_issue_with_required_custom_field
210 field = IssueCustomField.find_by_name('Database')
210 field = IssueCustomField.find_by_name('Database')
211 field.update_attribute(:is_required, true)
211 field.update_attribute(:is_required, true)
212
212
213 issue = Issue.find(1)
213 issue = Issue.find(1)
214 assert_nil issue.custom_value_for(field)
214 assert_nil issue.custom_value_for(field)
215 assert issue.available_custom_fields.include?(field)
215 assert issue.available_custom_fields.include?(field)
216 # No change to custom values, issue can be saved
216 # No change to custom values, issue can be saved
217 assert issue.save
217 assert issue.save
218 # Blank value
218 # Blank value
219 issue.custom_field_values = { field.id => '' }
219 issue.custom_field_values = { field.id => '' }
220 assert !issue.save
220 assert !issue.save
221 # Valid value
221 # Valid value
222 issue.custom_field_values = { field.id => 'PostgreSQL' }
222 issue.custom_field_values = { field.id => 'PostgreSQL' }
223 assert issue.save
223 assert issue.save
224 issue.reload
224 issue.reload
225 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
225 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
226 end
226 end
227
227
228 def test_should_not_update_attributes_if_custom_fields_validation_fails
228 def test_should_not_update_attributes_if_custom_fields_validation_fails
229 issue = Issue.find(1)
229 issue = Issue.find(1)
230 field = IssueCustomField.find_by_name('Database')
230 field = IssueCustomField.find_by_name('Database')
231 assert issue.available_custom_fields.include?(field)
231 assert issue.available_custom_fields.include?(field)
232
232
233 issue.custom_field_values = { field.id => 'Invalid' }
233 issue.custom_field_values = { field.id => 'Invalid' }
234 issue.subject = 'Should be not be saved'
234 issue.subject = 'Should be not be saved'
235 assert !issue.save
235 assert !issue.save
236
236
237 issue.reload
237 issue.reload
238 assert_equal "Can't print recipes", issue.subject
238 assert_equal "Can't print recipes", issue.subject
239 end
239 end
240
240
241 def test_should_not_recreate_custom_values_objects_on_update
241 def test_should_not_recreate_custom_values_objects_on_update
242 field = IssueCustomField.find_by_name('Database')
242 field = IssueCustomField.find_by_name('Database')
243
243
244 issue = Issue.find(1)
244 issue = Issue.find(1)
245 issue.custom_field_values = { field.id => 'PostgreSQL' }
245 issue.custom_field_values = { field.id => 'PostgreSQL' }
246 assert issue.save
246 assert issue.save
247 custom_value = issue.custom_value_for(field)
247 custom_value = issue.custom_value_for(field)
248 issue.reload
248 issue.reload
249 issue.custom_field_values = { field.id => 'MySQL' }
249 issue.custom_field_values = { field.id => 'MySQL' }
250 assert issue.save
250 assert issue.save
251 issue.reload
251 issue.reload
252 assert_equal custom_value.id, issue.custom_value_for(field).id
252 assert_equal custom_value.id, issue.custom_value_for(field).id
253 end
253 end
254
254
255 def test_assigning_tracker_id_should_reload_custom_fields_values
255 def test_assigning_tracker_id_should_reload_custom_fields_values
256 issue = Issue.new(:project => Project.find(1))
256 issue = Issue.new(:project => Project.find(1))
257 assert issue.custom_field_values.empty?
257 assert issue.custom_field_values.empty?
258 issue.tracker_id = 1
258 issue.tracker_id = 1
259 assert issue.custom_field_values.any?
259 assert issue.custom_field_values.any?
260 end
260 end
261
261
262 def test_assigning_attributes_should_assign_tracker_id_first
262 def test_assigning_attributes_should_assign_tracker_id_first
263 attributes = ActiveSupport::OrderedHash.new
263 attributes = ActiveSupport::OrderedHash.new
264 attributes['custom_field_values'] = { '1' => 'MySQL' }
264 attributes['custom_field_values'] = { '1' => 'MySQL' }
265 attributes['tracker_id'] = '1'
265 attributes['tracker_id'] = '1'
266 issue = Issue.new(:project => Project.find(1))
266 issue = Issue.new(:project => Project.find(1))
267 issue.attributes = attributes
267 issue.attributes = attributes
268 assert_not_nil issue.custom_value_for(1)
268 assert_not_nil issue.custom_value_for(1)
269 assert_equal 'MySQL', issue.custom_value_for(1).value
269 assert_equal 'MySQL', issue.custom_value_for(1).value
270 end
270 end
271
271
272 def test_should_update_issue_with_disabled_tracker
272 def test_should_update_issue_with_disabled_tracker
273 p = Project.find(1)
273 p = Project.find(1)
274 issue = Issue.find(1)
274 issue = Issue.find(1)
275
275
276 p.trackers.delete(issue.tracker)
276 p.trackers.delete(issue.tracker)
277 assert !p.trackers.include?(issue.tracker)
277 assert !p.trackers.include?(issue.tracker)
278
278
279 issue.reload
279 issue.reload
280 issue.subject = 'New subject'
280 issue.subject = 'New subject'
281 assert issue.save
281 assert issue.save
282 end
282 end
283
283
284 def test_should_not_set_a_disabled_tracker
284 def test_should_not_set_a_disabled_tracker
285 p = Project.find(1)
285 p = Project.find(1)
286 p.trackers.delete(Tracker.find(2))
286 p.trackers.delete(Tracker.find(2))
287
287
288 issue = Issue.find(1)
288 issue = Issue.find(1)
289 issue.tracker_id = 2
289 issue.tracker_id = 2
290 issue.subject = 'New subject'
290 issue.subject = 'New subject'
291 assert !issue.save
291 assert !issue.save
292 assert_not_nil issue.errors.on(:tracker_id)
292 assert_not_nil issue.errors.on(:tracker_id)
293 end
293 end
294
294
295 def test_category_based_assignment
295 def test_category_based_assignment
296 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
296 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
297 :status_id => 1, :priority => IssuePriority.all.first,
297 :status_id => 1, :priority => IssuePriority.all.first,
298 :subject => 'Assignment test',
298 :subject => 'Assignment test',
299 :description => 'Assignment test', :category_id => 1)
299 :description => 'Assignment test', :category_id => 1)
300 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
300 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
301 end
301 end
302
302
303 def test_new_statuses_allowed_to
303 def test_new_statuses_allowed_to
304 Workflow.delete_all
304 Workflow.delete_all
305
305
306 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
306 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
307 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
307 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
308 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
308 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
309 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
309 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
310 status = IssueStatus.find(1)
310 status = IssueStatus.find(1)
311 role = Role.find(1)
311 role = Role.find(1)
312 tracker = Tracker.find(1)
312 tracker = Tracker.find(1)
313 user = User.find(2)
313 user = User.find(2)
314
314
315 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1)
315 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1)
316 assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id)
316 assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id)
317
317
318 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user)
318 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user)
319 assert_equal [1, 2, 3, 5], issue.new_statuses_allowed_to(user).map(&:id)
319 assert_equal [1, 2, 3, 5], issue.new_statuses_allowed_to(user).map(&:id)
320
320
321 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :assigned_to => user)
321 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :assigned_to => user)
322 assert_equal [1, 2, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
322 assert_equal [1, 2, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
323
323
324 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user, :assigned_to => user)
324 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user, :assigned_to => user)
325 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
325 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
326 end
326 end
327
327
328 def test_copy
328 def test_copy
329 issue = Issue.new.copy_from(1)
329 issue = Issue.new.copy_from(1)
330 assert issue.save
330 assert issue.save
331 issue.reload
331 issue.reload
332 orig = Issue.find(1)
332 orig = Issue.find(1)
333 assert_equal orig.subject, issue.subject
333 assert_equal orig.subject, issue.subject
334 assert_equal orig.tracker, issue.tracker
334 assert_equal orig.tracker, issue.tracker
335 assert_equal "125", issue.custom_value_for(2).value
335 assert_equal "125", issue.custom_value_for(2).value
336 end
336 end
337
337
338 def test_copy_should_copy_status
338 def test_copy_should_copy_status
339 orig = Issue.find(8)
339 orig = Issue.find(8)
340 assert orig.status != IssueStatus.default
340 assert orig.status != IssueStatus.default
341
341
342 issue = Issue.new.copy_from(orig)
342 issue = Issue.new.copy_from(orig)
343 assert issue.save
343 assert issue.save
344 issue.reload
344 issue.reload
345 assert_equal orig.status, issue.status
345 assert_equal orig.status, issue.status
346 end
346 end
347
347
348 def test_should_close_duplicates
348 def test_should_close_duplicates
349 # Create 3 issues
349 # Create 3 issues
350 issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
350 issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
351 assert issue1.save
351 assert issue1.save
352 issue2 = issue1.clone
352 issue2 = issue1.clone
353 assert issue2.save
353 assert issue2.save
354 issue3 = issue1.clone
354 issue3 = issue1.clone
355 assert issue3.save
355 assert issue3.save
356
356
357 # 2 is a dupe of 1
357 # 2 is a dupe of 1
358 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
358 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
359 # And 3 is a dupe of 2
359 # And 3 is a dupe of 2
360 IssueRelation.create(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
360 IssueRelation.create(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
361 # And 3 is a dupe of 1 (circular duplicates)
361 # And 3 is a dupe of 1 (circular duplicates)
362 IssueRelation.create(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
362 IssueRelation.create(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
363
363
364 assert issue1.reload.duplicates.include?(issue2)
364 assert issue1.reload.duplicates.include?(issue2)
365
365
366 # Closing issue 1
366 # Closing issue 1
367 issue1.init_journal(User.find(:first), "Closing issue1")
367 issue1.init_journal(User.find(:first), "Closing issue1")
368 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
368 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
369 assert issue1.save
369 assert issue1.save
370 # 2 and 3 should be also closed
370 # 2 and 3 should be also closed
371 assert issue2.reload.closed?
371 assert issue2.reload.closed?
372 assert issue3.reload.closed?
372 assert issue3.reload.closed?
373 end
373 end
374
374
375 def test_should_not_close_duplicated_issue
375 def test_should_not_close_duplicated_issue
376 # Create 3 issues
376 # Create 3 issues
377 issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
377 issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'Duplicates test', :description => 'Duplicates test')
378 assert issue1.save
378 assert issue1.save
379 issue2 = issue1.clone
379 issue2 = issue1.clone
380 assert issue2.save
380 assert issue2.save
381
381
382 # 2 is a dupe of 1
382 # 2 is a dupe of 1
383 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
383 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
384 # 2 is a dup of 1 but 1 is not a duplicate of 2
384 # 2 is a dup of 1 but 1 is not a duplicate of 2
385 assert !issue2.reload.duplicates.include?(issue1)
385 assert !issue2.reload.duplicates.include?(issue1)
386
386
387 # Closing issue 2
387 # Closing issue 2
388 issue2.init_journal(User.find(:first), "Closing issue2")
388 issue2.init_journal(User.find(:first), "Closing issue2")
389 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
389 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
390 assert issue2.save
390 assert issue2.save
391 # 1 should not be also closed
391 # 1 should not be also closed
392 assert !issue1.reload.closed?
392 assert !issue1.reload.closed?
393 end
393 end
394
394
395 def test_assignable_versions
395 def test_assignable_versions
396 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
396 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
397 assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
397 assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
398 end
398 end
399
399
400 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
400 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
401 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
401 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
402 assert !issue.save
402 assert !issue.save
403 assert_not_nil issue.errors.on(:fixed_version_id)
403 assert_not_nil issue.errors.on(:fixed_version_id)
404 end
404 end
405
405
406 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
406 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
407 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
407 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
408 assert !issue.save
408 assert !issue.save
409 assert_not_nil issue.errors.on(:fixed_version_id)
409 assert_not_nil issue.errors.on(:fixed_version_id)
410 end
410 end
411
411
412 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
412 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
413 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
413 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
414 assert issue.save
414 assert issue.save
415 end
415 end
416
416
417 def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
417 def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
418 issue = Issue.find(11)
418 issue = Issue.find(11)
419 assert_equal 'closed', issue.fixed_version.status
419 assert_equal 'closed', issue.fixed_version.status
420 issue.subject = 'Subject changed'
420 issue.subject = 'Subject changed'
421 assert issue.save
421 assert issue.save
422 end
422 end
423
423
424 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
424 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
425 issue = Issue.find(11)
425 issue = Issue.find(11)
426 issue.status_id = 1
426 issue.status_id = 1
427 assert !issue.save
427 assert !issue.save
428 assert_not_nil issue.errors.on_base
428 assert_not_nil issue.errors.on_base
429 end
429 end
430
430
431 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
431 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
432 issue = Issue.find(11)
432 issue = Issue.find(11)
433 issue.status_id = 1
433 issue.status_id = 1
434 issue.fixed_version_id = 3
434 issue.fixed_version_id = 3
435 assert issue.save
435 assert issue.save
436 end
436 end
437
437
438 def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
438 def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
439 issue = Issue.find(12)
439 issue = Issue.find(12)
440 assert_equal 'locked', issue.fixed_version.status
440 assert_equal 'locked', issue.fixed_version.status
441 issue.status_id = 1
441 issue.status_id = 1
442 assert issue.save
442 assert issue.save
443 end
443 end
444
444
445 def test_move_to_another_project_with_same_category
445 def test_move_to_another_project_with_same_category
446 issue = Issue.find(1)
446 issue = Issue.find(1)
447 assert issue.move_to_project(Project.find(2))
447 assert issue.move_to_project(Project.find(2))
448 issue.reload
448 issue.reload
449 assert_equal 2, issue.project_id
449 assert_equal 2, issue.project_id
450 # Category changes
450 # Category changes
451 assert_equal 4, issue.category_id
451 assert_equal 4, issue.category_id
452 # Make sure time entries were move to the target project
452 # Make sure time entries were move to the target project
453 assert_equal 2, issue.time_entries.first.project_id
453 assert_equal 2, issue.time_entries.first.project_id
454 end
454 end
455
455
456 def test_move_to_another_project_without_same_category
456 def test_move_to_another_project_without_same_category
457 issue = Issue.find(2)
457 issue = Issue.find(2)
458 assert issue.move_to_project(Project.find(2))
458 assert issue.move_to_project(Project.find(2))
459 issue.reload
459 issue.reload
460 assert_equal 2, issue.project_id
460 assert_equal 2, issue.project_id
461 # Category cleared
461 # Category cleared
462 assert_nil issue.category_id
462 assert_nil issue.category_id
463 end
463 end
464
464
465 def test_move_to_another_project_should_clear_fixed_version_when_not_shared
465 def test_move_to_another_project_should_clear_fixed_version_when_not_shared
466 issue = Issue.find(1)
466 issue = Issue.find(1)
467 issue.update_attribute(:fixed_version_id, 1)
467 issue.update_attribute(:fixed_version_id, 1)
468 assert issue.move_to_project(Project.find(2))
468 assert issue.move_to_project(Project.find(2))
469 issue.reload
469 issue.reload
470 assert_equal 2, issue.project_id
470 assert_equal 2, issue.project_id
471 # Cleared fixed_version
471 # Cleared fixed_version
472 assert_equal nil, issue.fixed_version
472 assert_equal nil, issue.fixed_version
473 end
473 end
474
474
475 def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
475 def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
476 issue = Issue.find(1)
476 issue = Issue.find(1)
477 issue.update_attribute(:fixed_version_id, 4)
477 issue.update_attribute(:fixed_version_id, 4)
478 assert issue.move_to_project(Project.find(5))
478 assert issue.move_to_project(Project.find(5))
479 issue.reload
479 issue.reload
480 assert_equal 5, issue.project_id
480 assert_equal 5, issue.project_id
481 # Keep fixed_version
481 # Keep fixed_version
482 assert_equal 4, issue.fixed_version_id
482 assert_equal 4, issue.fixed_version_id
483 end
483 end
484
484
485 def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
485 def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
486 issue = Issue.find(1)
486 issue = Issue.find(1)
487 issue.update_attribute(:fixed_version_id, 1)
487 issue.update_attribute(:fixed_version_id, 1)
488 assert issue.move_to_project(Project.find(5))
488 assert issue.move_to_project(Project.find(5))
489 issue.reload
489 issue.reload
490 assert_equal 5, issue.project_id
490 assert_equal 5, issue.project_id
491 # Cleared fixed_version
491 # Cleared fixed_version
492 assert_equal nil, issue.fixed_version
492 assert_equal nil, issue.fixed_version
493 end
493 end
494
494
495 def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
495 def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
496 issue = Issue.find(1)
496 issue = Issue.find(1)
497 issue.update_attribute(:fixed_version_id, 7)
497 issue.update_attribute(:fixed_version_id, 7)
498 assert issue.move_to_project(Project.find(2))
498 assert issue.move_to_project(Project.find(2))
499 issue.reload
499 issue.reload
500 assert_equal 2, issue.project_id
500 assert_equal 2, issue.project_id
501 # Keep fixed_version
501 # Keep fixed_version
502 assert_equal 7, issue.fixed_version_id
502 assert_equal 7, issue.fixed_version_id
503 end
503 end
504
504
505 def test_move_to_another_project_with_disabled_tracker
505 def test_move_to_another_project_with_disabled_tracker
506 issue = Issue.find(1)
506 issue = Issue.find(1)
507 target = Project.find(2)
507 target = Project.find(2)
508 target.tracker_ids = [3]
508 target.tracker_ids = [3]
509 target.save
509 target.save
510 assert_equal false, issue.move_to_project(target)
510 assert_equal false, issue.move_to_project(target)
511 issue.reload
511 issue.reload
512 assert_equal 1, issue.project_id
512 assert_equal 1, issue.project_id
513 end
513 end
514
514
515 def test_copy_to_the_same_project
515 def test_copy_to_the_same_project
516 issue = Issue.find(1)
516 issue = Issue.find(1)
517 copy = nil
517 copy = nil
518 assert_difference 'Issue.count' do
518 assert_difference 'Issue.count' do
519 copy = issue.move_to_project(issue.project, nil, :copy => true)
519 copy = issue.move_to_project(issue.project, nil, :copy => true)
520 end
520 end
521 assert_kind_of Issue, copy
521 assert_kind_of Issue, copy
522 assert_equal issue.project, copy.project
522 assert_equal issue.project, copy.project
523 assert_equal "125", copy.custom_value_for(2).value
523 assert_equal "125", copy.custom_value_for(2).value
524 end
524 end
525
525
526 def test_copy_to_another_project_and_tracker
526 def test_copy_to_another_project_and_tracker
527 issue = Issue.find(1)
527 issue = Issue.find(1)
528 copy = nil
528 copy = nil
529 assert_difference 'Issue.count' do
529 assert_difference 'Issue.count' do
530 copy = issue.move_to_project(Project.find(3), Tracker.find(2), :copy => true)
530 copy = issue.move_to_project(Project.find(3), Tracker.find(2), :copy => true)
531 end
531 end
532 copy.reload
532 copy.reload
533 assert_kind_of Issue, copy
533 assert_kind_of Issue, copy
534 assert_equal Project.find(3), copy.project
534 assert_equal Project.find(3), copy.project
535 assert_equal Tracker.find(2), copy.tracker
535 assert_equal Tracker.find(2), copy.tracker
536 # Custom field #2 is not associated with target tracker
536 # Custom field #2 is not associated with target tracker
537 assert_nil copy.custom_value_for(2)
537 assert_nil copy.custom_value_for(2)
538 end
538 end
539
539
540 context "#move_to_project" do
540 context "#move_to_project" do
541 context "as a copy" do
541 context "as a copy" do
542 setup do
542 setup do
543 @issue = Issue.find(1)
543 @issue = Issue.find(1)
544 @copy = nil
544 @copy = nil
545 end
545 end
546
546
547 should "not create a journal" do
547 should "not create a journal" do
548 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
548 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
549 assert_equal 0, @copy.reload.journals.size
549 assert_equal 0, @copy.reload.journals.size
550 end
550 end
551
551
552 should "allow assigned_to changes" do
552 should "allow assigned_to changes" do
553 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
553 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
554 assert_equal 3, @copy.assigned_to_id
554 assert_equal 3, @copy.assigned_to_id
555 end
555 end
556
556
557 should "allow status changes" do
557 should "allow status changes" do
558 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:status_id => 2}})
558 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:status_id => 2}})
559 assert_equal 2, @copy.status_id
559 assert_equal 2, @copy.status_id
560 end
560 end
561
561
562 should "allow start date changes" do
562 should "allow start date changes" do
563 date = Date.today
563 date = Date.today
564 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
564 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
565 assert_equal date, @copy.start_date
565 assert_equal date, @copy.start_date
566 end
566 end
567
567
568 should "allow due date changes" do
568 should "allow due date changes" do
569 date = Date.today
569 date = Date.today
570 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:due_date => date}})
570 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:due_date => date}})
571
571
572 assert_equal date, @copy.due_date
572 assert_equal date, @copy.due_date
573 end
573 end
574
574
575 should "set current user as author" do
575 should "set current user as author" do
576 User.current = User.find(9)
576 User.current = User.find(9)
577 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {}})
577 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {}})
578
578
579 assert_equal User.current, @copy.author
579 assert_equal User.current, @copy.author
580 end
580 end
581
581
582 should "keep journal notes" do
582 should "keep journal notes" do
583 date = Date.today
583 date = Date.today
584 notes = "Notes added when copying"
584 notes = "Notes added when copying"
585 User.current = User.find(9)
585 User.current = User.find(9)
586 @issue.init_journal(User.current, notes)
586 @issue.init_journal(User.current, notes)
587 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
587 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
588
588
589 assert_equal 1, @copy.journals.size
589 assert_equal 1, @copy.journals.size
590 journal = @copy.journals.first
590 journal = @copy.journals.first
591 assert_equal 0, journal.details.size
591 assert_equal 0, journal.details.size
592 assert_equal notes, journal.notes
592 assert_equal notes, journal.notes
593 end
593 end
594 end
594 end
595 end
595 end
596
596
597 def test_recipients_should_not_include_users_that_cannot_view_the_issue
597 def test_recipients_should_not_include_users_that_cannot_view_the_issue
598 issue = Issue.find(12)
598 issue = Issue.find(12)
599 assert issue.recipients.include?(issue.author.mail)
599 assert issue.recipients.include?(issue.author.mail)
600 # move the issue to a private project
600 # move the issue to a private project
601 copy = issue.move_to_project(Project.find(5), Tracker.find(2), :copy => true)
601 copy = issue.move_to_project(Project.find(5), Tracker.find(2), :copy => true)
602 # author is not a member of project anymore
602 # author is not a member of project anymore
603 assert !copy.recipients.include?(copy.author.mail)
603 assert !copy.recipients.include?(copy.author.mail)
604 end
604 end
605
605
606 def test_recipients_should_include_the_assigned_group_members
606 def test_recipients_should_include_the_assigned_group_members
607 group_member = User.generate_with_protected!
607 group_member = User.generate_with_protected!
608 group = Group.generate!
608 group = Group.generate!
609 group.users << group_member
609 group.users << group_member
610
610
611 issue = Issue.find(12)
611 issue = Issue.find(12)
612 issue.assigned_to = group
612 issue.assigned_to = group
613 assert issue.recipients.include?(group_member.mail)
613 assert issue.recipients.include?(group_member.mail)
614 end
614 end
615
615
616 def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
616 def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
617 user = User.find(3)
617 user = User.find(3)
618 issue = Issue.find(9)
618 issue = Issue.find(9)
619 Watcher.create!(:user => user, :watchable => issue)
619 Watcher.create!(:user => user, :watchable => issue)
620 assert issue.watched_by?(user)
620 assert issue.watched_by?(user)
621 assert !issue.watcher_recipients.include?(user.mail)
621 assert !issue.watcher_recipients.include?(user.mail)
622 end
622 end
623
623
624 def test_issue_destroy
624 def test_issue_destroy
625 Issue.find(1).destroy
625 Issue.find(1).destroy
626 assert_nil Issue.find_by_id(1)
626 assert_nil Issue.find_by_id(1)
627 assert_nil TimeEntry.find_by_issue_id(1)
627 assert_nil TimeEntry.find_by_issue_id(1)
628 end
628 end
629
629
630 def test_blocked
630 def test_blocked
631 blocked_issue = Issue.find(9)
631 blocked_issue = Issue.find(9)
632 blocking_issue = Issue.find(10)
632 blocking_issue = Issue.find(10)
633
633
634 assert blocked_issue.blocked?
634 assert blocked_issue.blocked?
635 assert !blocking_issue.blocked?
635 assert !blocking_issue.blocked?
636 end
636 end
637
637
638 def test_blocked_issues_dont_allow_closed_statuses
638 def test_blocked_issues_dont_allow_closed_statuses
639 blocked_issue = Issue.find(9)
639 blocked_issue = Issue.find(9)
640
640
641 allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
641 allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
642 assert !allowed_statuses.empty?
642 assert !allowed_statuses.empty?
643 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
643 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
644 assert closed_statuses.empty?
644 assert closed_statuses.empty?
645 end
645 end
646
646
647 def test_unblocked_issues_allow_closed_statuses
647 def test_unblocked_issues_allow_closed_statuses
648 blocking_issue = Issue.find(10)
648 blocking_issue = Issue.find(10)
649
649
650 allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
650 allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
651 assert !allowed_statuses.empty?
651 assert !allowed_statuses.empty?
652 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
652 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
653 assert !closed_statuses.empty?
653 assert !closed_statuses.empty?
654 end
654 end
655
655
656 def test_rescheduling_an_issue_should_reschedule_following_issue
656 def test_rescheduling_an_issue_should_reschedule_following_issue
657 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
657 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
658 issue2 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
658 issue2 = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => '-', :start_date => Date.today, :due_date => Date.today + 2)
659 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
659 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
660 assert_equal issue1.due_date + 1, issue2.reload.start_date
660 assert_equal issue1.due_date + 1, issue2.reload.start_date
661
661
662 issue1.due_date = Date.today + 5
662 issue1.due_date = Date.today + 5
663 issue1.save!
663 issue1.save!
664 assert_equal issue1.due_date + 1, issue2.reload.start_date
664 assert_equal issue1.due_date + 1, issue2.reload.start_date
665 end
665 end
666
666
667 def test_overdue
667 def test_overdue
668 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
668 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
669 assert !Issue.new(:due_date => Date.today).overdue?
669 assert !Issue.new(:due_date => Date.today).overdue?
670 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
670 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
671 assert !Issue.new(:due_date => nil).overdue?
671 assert !Issue.new(:due_date => nil).overdue?
672 assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
672 assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
673 end
673 end
674
674
675 context "#behind_schedule?" do
675 context "#behind_schedule?" do
676 should "be false if the issue has no start_date" do
676 should "be false if the issue has no start_date" do
677 assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
677 assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
678 end
678 end
679
679
680 should "be false if the issue has no end_date" do
680 should "be false if the issue has no end_date" do
681 assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
681 assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
682 end
682 end
683
683
684 should "be false if the issue has more done than it's calendar time" do
684 should "be false if the issue has more done than it's calendar time" do
685 assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
685 assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
686 end
686 end
687
687
688 should "be true if the issue hasn't been started at all" do
688 should "be true if the issue hasn't been started at all" do
689 assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
689 assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
690 end
690 end
691
691
692 should "be true if the issue has used more calendar time than it's done ratio" do
692 should "be true if the issue has used more calendar time than it's done ratio" do
693 assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
693 assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
694 end
694 end
695 end
695 end
696
696
697 context "#assignable_users" do
697 context "#assignable_users" do
698 should "be Users" do
698 should "be Users" do
699 assert_kind_of User, Issue.find(1).assignable_users.first
699 assert_kind_of User, Issue.find(1).assignable_users.first
700 end
700 end
701
701
702 should "include the issue author" do
702 should "include the issue author" do
703 project = Project.find(1)
703 project = Project.find(1)
704 non_project_member = User.generate!
704 non_project_member = User.generate!
705 issue = Issue.generate_for_project!(project, :author => non_project_member)
705 issue = Issue.generate_for_project!(project, :author => non_project_member)
706
706
707 assert issue.assignable_users.include?(non_project_member)
707 assert issue.assignable_users.include?(non_project_member)
708 end
708 end
709
709
710 should "include the current assignee" do
710 should "include the current assignee" do
711 project = Project.find(1)
711 project = Project.find(1)
712 user = User.generate!
712 user = User.generate!
713 issue = Issue.generate_for_project!(project, :assigned_to => user)
713 issue = Issue.generate_for_project!(project, :assigned_to => user)
714 user.lock!
714 user.lock!
715
715
716 assert Issue.find(issue.id).assignable_users.include?(user)
716 assert Issue.find(issue.id).assignable_users.include?(user)
717 end
717 end
718
718
719 should "not show the issue author twice" do
719 should "not show the issue author twice" do
720 assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
720 assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
721 assert_equal 2, assignable_user_ids.length
721 assert_equal 2, assignable_user_ids.length
722
722
723 assignable_user_ids.each do |user_id|
723 assignable_user_ids.each do |user_id|
724 assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, "User #{user_id} appears more or less than once"
724 assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, "User #{user_id} appears more or less than once"
725 end
725 end
726 end
726 end
727
727
728 context "with issue_group_assignment" do
728 context "with issue_group_assignment" do
729 should "include groups" do
729 should "include groups" do
730 issue = Issue.new(:project => Project.find(2))
730 issue = Issue.new(:project => Project.find(2))
731
731
732 with_settings :issue_group_assignment => '1' do
732 with_settings :issue_group_assignment => '1' do
733 assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
733 assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
734 assert issue.assignable_users.include?(Group.find(11))
734 assert issue.assignable_users.include?(Group.find(11))
735 end
735 end
736 end
736 end
737 end
737 end
738
738
739 context "without issue_group_assignment" do
739 context "without issue_group_assignment" do
740 should "not include groups" do
740 should "not include groups" do
741 issue = Issue.new(:project => Project.find(2))
741 issue = Issue.new(:project => Project.find(2))
742
742
743 with_settings :issue_group_assignment => '0' do
743 with_settings :issue_group_assignment => '0' do
744 assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
744 assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
745 assert !issue.assignable_users.include?(Group.find(11))
745 assert !issue.assignable_users.include?(Group.find(11))
746 end
746 end
747 end
747 end
748 end
748 end
749 end
749 end
750
750
751 def test_create_should_send_email_notification
751 def test_create_should_send_email_notification
752 ActionMailer::Base.deliveries.clear
752 ActionMailer::Base.deliveries.clear
753 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_create', :estimated_hours => '1:30')
753 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => IssuePriority.all.first, :subject => 'test_create', :estimated_hours => '1:30')
754
754
755 assert issue.save
755 assert issue.save
756 assert_equal 1, ActionMailer::Base.deliveries.size
756 assert_equal 1, ActionMailer::Base.deliveries.size
757 end
757 end
758
758
759 def test_stale_issue_should_not_send_email_notification
759 def test_stale_issue_should_not_send_email_notification
760 ActionMailer::Base.deliveries.clear
760 ActionMailer::Base.deliveries.clear
761 issue = Issue.find(1)
761 issue = Issue.find(1)
762 stale = Issue.find(1)
762 stale = Issue.find(1)
763
763
764 issue.init_journal(User.find(1))
764 issue.init_journal(User.find(1))
765 issue.subject = 'Subjet update'
765 issue.subject = 'Subjet update'
766 assert issue.save
766 assert issue.save
767 assert_equal 1, ActionMailer::Base.deliveries.size
767 assert_equal 1, ActionMailer::Base.deliveries.size
768 ActionMailer::Base.deliveries.clear
768 ActionMailer::Base.deliveries.clear
769
769
770 stale.init_journal(User.find(1))
770 stale.init_journal(User.find(1))
771 stale.subject = 'Another subjet update'
771 stale.subject = 'Another subjet update'
772 assert_raise ActiveRecord::StaleObjectError do
772 assert_raise ActiveRecord::StaleObjectError do
773 stale.save
773 stale.save
774 end
774 end
775 assert ActionMailer::Base.deliveries.empty?
775 assert ActionMailer::Base.deliveries.empty?
776 end
776 end
777
777
778 def test_journalized_description
778 def test_journalized_description
779 IssueCustomField.delete_all
779 IssueCustomField.delete_all
780
780
781 i = Issue.first
781 i = Issue.first
782 old_description = i.description
782 old_description = i.description
783 new_description = "This is the new description"
783 new_description = "This is the new description"
784
784
785 i.init_journal(User.find(2))
785 i.init_journal(User.find(2))
786 i.description = new_description
786 i.description = new_description
787 assert_difference 'Journal.count', 1 do
787 assert_difference 'Journal.count', 1 do
788 assert_difference 'JournalDetail.count', 1 do
788 assert_difference 'JournalDetail.count', 1 do
789 i.save!
789 i.save!
790 end
790 end
791 end
791 end
792
792
793 detail = JournalDetail.first(:order => 'id DESC')
793 detail = JournalDetail.first(:order => 'id DESC')
794 assert_equal i, detail.journal.journalized
794 assert_equal i, detail.journal.journalized
795 assert_equal 'attr', detail.property
795 assert_equal 'attr', detail.property
796 assert_equal 'description', detail.prop_key
796 assert_equal 'description', detail.prop_key
797 assert_equal old_description, detail.old_value
797 assert_equal old_description, detail.old_value
798 assert_equal new_description, detail.value
798 assert_equal new_description, detail.value
799 end
799 end
800
800
801 def test_blank_descriptions_should_not_be_journalized
801 def test_blank_descriptions_should_not_be_journalized
802 IssueCustomField.delete_all
802 IssueCustomField.delete_all
803 Issue.update_all("description = NULL", "id=1")
803 Issue.update_all("description = NULL", "id=1")
804
804
805 i = Issue.find(1)
805 i = Issue.find(1)
806 i.init_journal(User.find(2))
806 i.init_journal(User.find(2))
807 i.subject = "blank description"
807 i.subject = "blank description"
808 i.description = "\r\n"
808 i.description = "\r\n"
809
809
810 assert_difference 'Journal.count', 1 do
810 assert_difference 'Journal.count', 1 do
811 assert_difference 'JournalDetail.count', 1 do
811 assert_difference 'JournalDetail.count', 1 do
812 i.save!
812 i.save!
813 end
813 end
814 end
814 end
815 end
815 end
816
816
817 def test_description_eol_should_be_normalized
817 def test_description_eol_should_be_normalized
818 i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
818 i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
819 assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
819 assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
820 end
820 end
821
821
822 def test_saving_twice_should_not_duplicate_journal_details
822 def test_saving_twice_should_not_duplicate_journal_details
823 i = Issue.find(:first)
823 i = Issue.find(:first)
824 i.init_journal(User.find(2), 'Some notes')
824 i.init_journal(User.find(2), 'Some notes')
825 # initial changes
825 # initial changes
826 i.subject = 'New subject'
826 i.subject = 'New subject'
827 i.done_ratio = i.done_ratio + 10
827 i.done_ratio = i.done_ratio + 10
828 assert_difference 'Journal.count' do
828 assert_difference 'Journal.count' do
829 assert i.save
829 assert i.save
830 end
830 end
831 # 1 more change
831 # 1 more change
832 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
832 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
833 assert_no_difference 'Journal.count' do
833 assert_no_difference 'Journal.count' do
834 assert_difference 'JournalDetail.count', 1 do
834 assert_difference 'JournalDetail.count', 1 do
835 i.save
835 i.save
836 end
836 end
837 end
837 end
838 # no more change
838 # no more change
839 assert_no_difference 'Journal.count' do
839 assert_no_difference 'Journal.count' do
840 assert_no_difference 'JournalDetail.count' do
840 assert_no_difference 'JournalDetail.count' do
841 i.save
841 i.save
842 end
842 end
843 end
843 end
844 end
844 end
845
845
846 def test_all_dependent_issues
846 def test_all_dependent_issues
847 IssueRelation.delete_all
847 IssueRelation.delete_all
848 assert IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => IssueRelation::TYPE_PRECEDES)
848 assert IssueRelation.create!(:issue_from => Issue.find(1),
849 assert IssueRelation.create!(:issue_from => Issue.find(2), :issue_to => Issue.find(3), :relation_type => IssueRelation::TYPE_PRECEDES)
849 :issue_to => Issue.find(2),
850 assert IssueRelation.create!(:issue_from => Issue.find(3), :issue_to => Issue.find(8), :relation_type => IssueRelation::TYPE_PRECEDES)
850 :relation_type => IssueRelation::TYPE_PRECEDES)
851 assert IssueRelation.create!(:issue_from => Issue.find(2),
852 :issue_to => Issue.find(3),
853 :relation_type => IssueRelation::TYPE_PRECEDES)
854 assert IssueRelation.create!(:issue_from => Issue.find(3),
855 :issue_to => Issue.find(8),
856 :relation_type => IssueRelation::TYPE_PRECEDES)
851
857
852 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
858 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
853 end
859 end
854
860
855 def test_all_dependent_issues_with_persistent_circular_dependency
861 def test_all_dependent_issues_with_persistent_circular_dependency
856 IssueRelation.delete_all
862 IssueRelation.delete_all
857 assert IssueRelation.create!(:issue_from => Issue.find(1),
863 assert IssueRelation.create!(:issue_from => Issue.find(1),
858 :issue_to => Issue.find(2),
864 :issue_to => Issue.find(2),
859 :relation_type => IssueRelation::TYPE_PRECEDES)
865 :relation_type => IssueRelation::TYPE_PRECEDES)
860 assert IssueRelation.create!(:issue_from => Issue.find(2),
866 assert IssueRelation.create!(:issue_from => Issue.find(2),
861 :issue_to => Issue.find(3),
867 :issue_to => Issue.find(3),
862 :relation_type => IssueRelation::TYPE_PRECEDES)
868 :relation_type => IssueRelation::TYPE_PRECEDES)
863 # Validation skipping
869 # Validation skipping
864 assert IssueRelation.new(:issue_from => Issue.find(3),
870 assert IssueRelation.new(:issue_from => Issue.find(3),
865 :issue_to => Issue.find(1),
871 :issue_to => Issue.find(1),
866 :relation_type => IssueRelation::TYPE_PRECEDES).save(false)
872 :relation_type => IssueRelation::TYPE_PRECEDES).save(false)
867
873
868 assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
874 assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
869 end
875 end
870
876
871 def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
877 def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
872 IssueRelation.delete_all
878 IssueRelation.delete_all
873 assert IssueRelation.create!(:issue_from => Issue.find(1),
879 assert IssueRelation.create!(:issue_from => Issue.find(1),
874 :issue_to => Issue.find(2),
880 :issue_to => Issue.find(2),
875 :relation_type => IssueRelation::TYPE_RELATES)
881 :relation_type => IssueRelation::TYPE_RELATES)
876 assert IssueRelation.create!(:issue_from => Issue.find(2),
882 assert IssueRelation.create!(:issue_from => Issue.find(2),
877 :issue_to => Issue.find(3),
883 :issue_to => Issue.find(3),
878 :relation_type => IssueRelation::TYPE_RELATES)
884 :relation_type => IssueRelation::TYPE_RELATES)
879 assert IssueRelation.create!(:issue_from => Issue.find(3),
885 assert IssueRelation.create!(:issue_from => Issue.find(3),
880 :issue_to => Issue.find(8),
886 :issue_to => Issue.find(8),
881 :relation_type => IssueRelation::TYPE_RELATES)
887 :relation_type => IssueRelation::TYPE_RELATES)
882 # Validation skipping
888 # Validation skipping
883 assert IssueRelation.new(:issue_from => Issue.find(8),
889 assert IssueRelation.new(:issue_from => Issue.find(8),
884 :issue_to => Issue.find(2),
890 :issue_to => Issue.find(2),
885 :relation_type => IssueRelation::TYPE_RELATES).save(false)
891 :relation_type => IssueRelation::TYPE_RELATES).save(false)
886 assert IssueRelation.new(:issue_from => Issue.find(3),
892 assert IssueRelation.new(:issue_from => Issue.find(3),
887 :issue_to => Issue.find(1),
893 :issue_to => Issue.find(1),
888 :relation_type => IssueRelation::TYPE_RELATES).save(false)
894 :relation_type => IssueRelation::TYPE_RELATES).save(false)
889
895
890 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
896 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
891 end
897 end
892
898
893 context "#done_ratio" do
899 context "#done_ratio" do
894 setup do
900 setup do
895 @issue = Issue.find(1)
901 @issue = Issue.find(1)
896 @issue_status = IssueStatus.find(1)
902 @issue_status = IssueStatus.find(1)
897 @issue_status.update_attribute(:default_done_ratio, 50)
903 @issue_status.update_attribute(:default_done_ratio, 50)
898 @issue2 = Issue.find(2)
904 @issue2 = Issue.find(2)
899 @issue_status2 = IssueStatus.find(2)
905 @issue_status2 = IssueStatus.find(2)
900 @issue_status2.update_attribute(:default_done_ratio, 0)
906 @issue_status2.update_attribute(:default_done_ratio, 0)
901 end
907 end
902
908
903 context "with Setting.issue_done_ratio using the issue_field" do
909 context "with Setting.issue_done_ratio using the issue_field" do
904 setup do
910 setup do
905 Setting.issue_done_ratio = 'issue_field'
911 Setting.issue_done_ratio = 'issue_field'
906 end
912 end
907
913
908 should "read the issue's field" do
914 should "read the issue's field" do
909 assert_equal 0, @issue.done_ratio
915 assert_equal 0, @issue.done_ratio
910 assert_equal 30, @issue2.done_ratio
916 assert_equal 30, @issue2.done_ratio
911 end
917 end
912 end
918 end
913
919
914 context "with Setting.issue_done_ratio using the issue_status" do
920 context "with Setting.issue_done_ratio using the issue_status" do
915 setup do
921 setup do
916 Setting.issue_done_ratio = 'issue_status'
922 Setting.issue_done_ratio = 'issue_status'
917 end
923 end
918
924
919 should "read the Issue Status's default done ratio" do
925 should "read the Issue Status's default done ratio" do
920 assert_equal 50, @issue.done_ratio
926 assert_equal 50, @issue.done_ratio
921 assert_equal 0, @issue2.done_ratio
927 assert_equal 0, @issue2.done_ratio
922 end
928 end
923 end
929 end
924 end
930 end
925
931
926 context "#update_done_ratio_from_issue_status" do
932 context "#update_done_ratio_from_issue_status" do
927 setup do
933 setup do
928 @issue = Issue.find(1)
934 @issue = Issue.find(1)
929 @issue_status = IssueStatus.find(1)
935 @issue_status = IssueStatus.find(1)
930 @issue_status.update_attribute(:default_done_ratio, 50)
936 @issue_status.update_attribute(:default_done_ratio, 50)
931 @issue2 = Issue.find(2)
937 @issue2 = Issue.find(2)
932 @issue_status2 = IssueStatus.find(2)
938 @issue_status2 = IssueStatus.find(2)
933 @issue_status2.update_attribute(:default_done_ratio, 0)
939 @issue_status2.update_attribute(:default_done_ratio, 0)
934 end
940 end
935
941
936 context "with Setting.issue_done_ratio using the issue_field" do
942 context "with Setting.issue_done_ratio using the issue_field" do
937 setup do
943 setup do
938 Setting.issue_done_ratio = 'issue_field'
944 Setting.issue_done_ratio = 'issue_field'
939 end
945 end
940
946
941 should "not change the issue" do
947 should "not change the issue" do
942 @issue.update_done_ratio_from_issue_status
948 @issue.update_done_ratio_from_issue_status
943 @issue2.update_done_ratio_from_issue_status
949 @issue2.update_done_ratio_from_issue_status
944
950
945 assert_equal 0, @issue.read_attribute(:done_ratio)
951 assert_equal 0, @issue.read_attribute(:done_ratio)
946 assert_equal 30, @issue2.read_attribute(:done_ratio)
952 assert_equal 30, @issue2.read_attribute(:done_ratio)
947 end
953 end
948 end
954 end
949
955
950 context "with Setting.issue_done_ratio using the issue_status" do
956 context "with Setting.issue_done_ratio using the issue_status" do
951 setup do
957 setup do
952 Setting.issue_done_ratio = 'issue_status'
958 Setting.issue_done_ratio = 'issue_status'
953 end
959 end
954
960
955 should "change the issue's done ratio" do
961 should "change the issue's done ratio" do
956 @issue.update_done_ratio_from_issue_status
962 @issue.update_done_ratio_from_issue_status
957 @issue2.update_done_ratio_from_issue_status
963 @issue2.update_done_ratio_from_issue_status
958
964
959 assert_equal 50, @issue.read_attribute(:done_ratio)
965 assert_equal 50, @issue.read_attribute(:done_ratio)
960 assert_equal 0, @issue2.read_attribute(:done_ratio)
966 assert_equal 0, @issue2.read_attribute(:done_ratio)
961 end
967 end
962 end
968 end
963 end
969 end
964
970
965 test "#by_tracker" do
971 test "#by_tracker" do
966 User.current = User.anonymous
972 User.current = User.anonymous
967 groups = Issue.by_tracker(Project.find(1))
973 groups = Issue.by_tracker(Project.find(1))
968 assert_equal 3, groups.size
974 assert_equal 3, groups.size
969 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
975 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
970 end
976 end
971
977
972 test "#by_version" do
978 test "#by_version" do
973 User.current = User.anonymous
979 User.current = User.anonymous
974 groups = Issue.by_version(Project.find(1))
980 groups = Issue.by_version(Project.find(1))
975 assert_equal 3, groups.size
981 assert_equal 3, groups.size
976 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
982 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
977 end
983 end
978
984
979 test "#by_priority" do
985 test "#by_priority" do
980 User.current = User.anonymous
986 User.current = User.anonymous
981 groups = Issue.by_priority(Project.find(1))
987 groups = Issue.by_priority(Project.find(1))
982 assert_equal 4, groups.size
988 assert_equal 4, groups.size
983 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
989 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
984 end
990 end
985
991
986 test "#by_category" do
992 test "#by_category" do
987 User.current = User.anonymous
993 User.current = User.anonymous
988 groups = Issue.by_category(Project.find(1))
994 groups = Issue.by_category(Project.find(1))
989 assert_equal 2, groups.size
995 assert_equal 2, groups.size
990 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
996 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
991 end
997 end
992
998
993 test "#by_assigned_to" do
999 test "#by_assigned_to" do
994 User.current = User.anonymous
1000 User.current = User.anonymous
995 groups = Issue.by_assigned_to(Project.find(1))
1001 groups = Issue.by_assigned_to(Project.find(1))
996 assert_equal 2, groups.size
1002 assert_equal 2, groups.size
997 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1003 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
998 end
1004 end
999
1005
1000 test "#by_author" do
1006 test "#by_author" do
1001 User.current = User.anonymous
1007 User.current = User.anonymous
1002 groups = Issue.by_author(Project.find(1))
1008 groups = Issue.by_author(Project.find(1))
1003 assert_equal 4, groups.size
1009 assert_equal 4, groups.size
1004 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1010 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1005 end
1011 end
1006
1012
1007 test "#by_subproject" do
1013 test "#by_subproject" do
1008 User.current = User.anonymous
1014 User.current = User.anonymous
1009 groups = Issue.by_subproject(Project.find(1))
1015 groups = Issue.by_subproject(Project.find(1))
1010 # Private descendant not visible
1016 # Private descendant not visible
1011 assert_equal 1, groups.size
1017 assert_equal 1, groups.size
1012 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1018 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1013 end
1019 end
1014
1020
1015 context ".allowed_target_projects_on_move" do
1021 context ".allowed_target_projects_on_move" do
1016 should "return all active projects for admin users" do
1022 should "return all active projects for admin users" do
1017 User.current = User.find(1)
1023 User.current = User.find(1)
1018 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
1024 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
1019 end
1025 end
1020
1026
1021 should "return allowed projects for non admin users" do
1027 should "return allowed projects for non admin users" do
1022 User.current = User.find(2)
1028 User.current = User.find(2)
1023 Role.non_member.remove_permission! :move_issues
1029 Role.non_member.remove_permission! :move_issues
1024 assert_equal 3, Issue.allowed_target_projects_on_move.size
1030 assert_equal 3, Issue.allowed_target_projects_on_move.size
1025
1031
1026 Role.non_member.add_permission! :move_issues
1032 Role.non_member.add_permission! :move_issues
1027 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
1033 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
1028 end
1034 end
1029 end
1035 end
1030
1036
1031 def test_recently_updated_with_limit_scopes
1037 def test_recently_updated_with_limit_scopes
1032 #should return the last updated issue
1038 #should return the last updated issue
1033 assert_equal 1, Issue.recently_updated.with_limit(1).length
1039 assert_equal 1, Issue.recently_updated.with_limit(1).length
1034 assert_equal Issue.find(:first, :order => "updated_on DESC"), Issue.recently_updated.with_limit(1).first
1040 assert_equal Issue.find(:first, :order => "updated_on DESC"), Issue.recently_updated.with_limit(1).first
1035 end
1041 end
1036
1042
1037 def test_on_active_projects_scope
1043 def test_on_active_projects_scope
1038 assert Project.find(2).archive
1044 assert Project.find(2).archive
1039
1045
1040 before = Issue.on_active_project.length
1046 before = Issue.on_active_project.length
1041 # test inclusion to results
1047 # test inclusion to results
1042 issue = Issue.generate_for_project!(Project.find(1), :tracker => Project.find(2).trackers.first)
1048 issue = Issue.generate_for_project!(Project.find(1), :tracker => Project.find(2).trackers.first)
1043 assert_equal before + 1, Issue.on_active_project.length
1049 assert_equal before + 1, Issue.on_active_project.length
1044
1050
1045 # Move to an archived project
1051 # Move to an archived project
1046 issue.project = Project.find(2)
1052 issue.project = Project.find(2)
1047 assert issue.save
1053 assert issue.save
1048 assert_equal before, Issue.on_active_project.length
1054 assert_equal before, Issue.on_active_project.length
1049 end
1055 end
1050
1056
1051 context "Issue#recipients" do
1057 context "Issue#recipients" do
1052 setup do
1058 setup do
1053 @project = Project.find(1)
1059 @project = Project.find(1)
1054 @author = User.generate_with_protected!
1060 @author = User.generate_with_protected!
1055 @assignee = User.generate_with_protected!
1061 @assignee = User.generate_with_protected!
1056 @issue = Issue.generate_for_project!(@project, :assigned_to => @assignee, :author => @author)
1062 @issue = Issue.generate_for_project!(@project, :assigned_to => @assignee, :author => @author)
1057 end
1063 end
1058
1064
1059 should "include project recipients" do
1065 should "include project recipients" do
1060 assert @project.recipients.present?
1066 assert @project.recipients.present?
1061 @project.recipients.each do |project_recipient|
1067 @project.recipients.each do |project_recipient|
1062 assert @issue.recipients.include?(project_recipient)
1068 assert @issue.recipients.include?(project_recipient)
1063 end
1069 end
1064 end
1070 end
1065
1071
1066 should "include the author if the author is active" do
1072 should "include the author if the author is active" do
1067 assert @issue.author, "No author set for Issue"
1073 assert @issue.author, "No author set for Issue"
1068 assert @issue.recipients.include?(@issue.author.mail)
1074 assert @issue.recipients.include?(@issue.author.mail)
1069 end
1075 end
1070
1076
1071 should "include the assigned to user if the assigned to user is active" do
1077 should "include the assigned to user if the assigned to user is active" do
1072 assert @issue.assigned_to, "No assigned_to set for Issue"
1078 assert @issue.assigned_to, "No assigned_to set for Issue"
1073 assert @issue.recipients.include?(@issue.assigned_to.mail)
1079 assert @issue.recipients.include?(@issue.assigned_to.mail)
1074 end
1080 end
1075
1081
1076 should "not include users who opt out of all email" do
1082 should "not include users who opt out of all email" do
1077 @author.update_attribute(:mail_notification, :none)
1083 @author.update_attribute(:mail_notification, :none)
1078
1084
1079 assert !@issue.recipients.include?(@issue.author.mail)
1085 assert !@issue.recipients.include?(@issue.author.mail)
1080 end
1086 end
1081
1087
1082 should "not include the issue author if they are only notified of assigned issues" do
1088 should "not include the issue author if they are only notified of assigned issues" do
1083 @author.update_attribute(:mail_notification, :only_assigned)
1089 @author.update_attribute(:mail_notification, :only_assigned)
1084
1090
1085 assert !@issue.recipients.include?(@issue.author.mail)
1091 assert !@issue.recipients.include?(@issue.author.mail)
1086 end
1092 end
1087
1093
1088 should "not include the assigned user if they are only notified of owned issues" do
1094 should "not include the assigned user if they are only notified of owned issues" do
1089 @assignee.update_attribute(:mail_notification, :only_owner)
1095 @assignee.update_attribute(:mail_notification, :only_owner)
1090
1096
1091 assert !@issue.recipients.include?(@issue.assigned_to.mail)
1097 assert !@issue.recipients.include?(@issue.assigned_to.mail)
1092 end
1098 end
1093
1099
1094 end
1100 end
1095 end
1101 end
General Comments 0
You need to be logged in to leave comments. Login now