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