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