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