##// END OF EJS Templates
add test of parent issue id beginning sharp to unit issue test (#11979)...
Toshi MARUYAMA -
r10406:b537a2f1decb
parent child
Show More
@@ -1,1662 +1,1681
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class 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 :groups_users,
22 :groups_users,
23 :trackers, :projects_trackers,
23 :trackers, :projects_trackers,
24 :enabled_modules,
24 :enabled_modules,
25 :versions,
25 :versions,
26 :issue_statuses, :issue_categories, :issue_relations, :workflows,
26 :issue_statuses, :issue_categories, :issue_relations, :workflows,
27 :enumerations,
27 :enumerations,
28 :issues, :journals, :journal_details,
28 :issues, :journals, :journal_details,
29 :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
29 :custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
30 :time_entries
30 :time_entries
31
31
32 include Redmine::I18n
32 include Redmine::I18n
33
33
34 def teardown
34 def teardown
35 User.current = nil
35 User.current = nil
36 end
36 end
37
37
38 def test_create
38 def test_create
39 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
39 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
40 :status_id => 1, :priority => IssuePriority.all.first,
40 :status_id => 1, :priority => IssuePriority.all.first,
41 :subject => 'test_create',
41 :subject => 'test_create',
42 :description => 'IssueTest#test_create', :estimated_hours => '1:30')
42 :description => 'IssueTest#test_create', :estimated_hours => '1:30')
43 assert issue.save
43 assert issue.save
44 issue.reload
44 issue.reload
45 assert_equal 1.5, issue.estimated_hours
45 assert_equal 1.5, issue.estimated_hours
46 end
46 end
47
47
48 def test_create_minimal
48 def test_create_minimal
49 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
49 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
50 :status_id => 1, :priority => IssuePriority.all.first,
50 :status_id => 1, :priority => IssuePriority.all.first,
51 :subject => 'test_create')
51 :subject => 'test_create')
52 assert issue.save
52 assert issue.save
53 assert issue.description.nil?
53 assert issue.description.nil?
54 assert_nil issue.estimated_hours
54 assert_nil issue.estimated_hours
55 end
55 end
56
56
57 def test_create_with_required_custom_field
57 def test_create_with_required_custom_field
58 set_language_if_valid 'en'
58 set_language_if_valid 'en'
59 field = IssueCustomField.find_by_name('Database')
59 field = IssueCustomField.find_by_name('Database')
60 field.update_attribute(:is_required, true)
60 field.update_attribute(:is_required, true)
61
61
62 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
62 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
63 :status_id => 1, :subject => 'test_create',
63 :status_id => 1, :subject => 'test_create',
64 :description => 'IssueTest#test_create_with_required_custom_field')
64 :description => 'IssueTest#test_create_with_required_custom_field')
65 assert issue.available_custom_fields.include?(field)
65 assert issue.available_custom_fields.include?(field)
66 # No value for the custom field
66 # No value for the custom field
67 assert !issue.save
67 assert !issue.save
68 assert_equal ["Database can't be blank"], issue.errors.full_messages
68 assert_equal ["Database can't be blank"], issue.errors.full_messages
69 # Blank value
69 # Blank value
70 issue.custom_field_values = { field.id => '' }
70 issue.custom_field_values = { field.id => '' }
71 assert !issue.save
71 assert !issue.save
72 assert_equal ["Database can't be blank"], issue.errors.full_messages
72 assert_equal ["Database can't be blank"], issue.errors.full_messages
73 # Invalid value
73 # Invalid value
74 issue.custom_field_values = { field.id => 'SQLServer' }
74 issue.custom_field_values = { field.id => 'SQLServer' }
75 assert !issue.save
75 assert !issue.save
76 assert_equal ["Database is not included in the list"], issue.errors.full_messages
76 assert_equal ["Database is not included in the list"], issue.errors.full_messages
77 # Valid value
77 # Valid value
78 issue.custom_field_values = { field.id => 'PostgreSQL' }
78 issue.custom_field_values = { field.id => 'PostgreSQL' }
79 assert issue.save
79 assert issue.save
80 issue.reload
80 issue.reload
81 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
81 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
82 end
82 end
83
83
84 def test_create_with_group_assignment
84 def test_create_with_group_assignment
85 with_settings :issue_group_assignment => '1' do
85 with_settings :issue_group_assignment => '1' do
86 assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
86 assert Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
87 :subject => 'Group assignment',
87 :subject => 'Group assignment',
88 :assigned_to_id => 11).save
88 :assigned_to_id => 11).save
89 issue = Issue.first(:order => 'id DESC')
89 issue = Issue.first(:order => 'id DESC')
90 assert_kind_of Group, issue.assigned_to
90 assert_kind_of Group, issue.assigned_to
91 assert_equal Group.find(11), issue.assigned_to
91 assert_equal Group.find(11), issue.assigned_to
92 end
92 end
93 end
93 end
94
94
95 def test_create_with_parent_issue_id
95 def test_create_with_parent_issue_id
96 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Group assignment', :parent_issue_id => 1)
96 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Group assignment', :parent_issue_id => 1)
97 assert_save issue
97 assert_save issue
98 assert_equal 1, issue.parent_issue_id
98 assert_equal 1, issue.parent_issue_id
99 assert_equal Issue.find(1), issue.parent
99 assert_equal Issue.find(1), issue.parent
100 end
100 end
101
101
102 def test_create_with_sharp_parent_issue_id
103 issue = Issue.new(:project_id => 1, :tracker_id => 1,
104 :author_id => 1, :subject => 'Group assignment',
105 :parent_issue_id => "#1")
106 assert_save issue
107 assert_equal 1, issue.parent_issue_id
108 assert_equal Issue.find(1), issue.parent
109 end
110
102 def test_create_with_invalid_parent_issue_id
111 def test_create_with_invalid_parent_issue_id
103 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Group assignment', :parent_issue_id => '01ABC')
112 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'Group assignment', :parent_issue_id => '01ABC')
104 assert !issue.save
113 assert !issue.save
105 assert_equal '01ABC', issue.parent_issue_id
114 assert_equal '01ABC', issue.parent_issue_id
106 assert_include 'Parent task is invalid', issue.errors.full_messages
115 assert_include 'Parent task is invalid', issue.errors.full_messages
107 end
116 end
108
117
118 def test_create_with_invalid_sharp_parent_issue_id
119 set_language_if_valid 'en'
120 issue = Issue.new(:project_id => 1, :tracker_id => 1,
121 :author_id => 1, :subject => 'Group assignment',
122 :parent_issue_id => '#01ABC')
123 assert !issue.save
124 assert_equal '#01ABC', issue.parent_issue_id
125 assert_include 'Parent task is invalid', issue.errors.full_messages
126 end
127
109 def assert_visibility_match(user, issues)
128 def assert_visibility_match(user, issues)
110 assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
129 assert_equal issues.collect(&:id).sort, Issue.all.select {|issue| issue.visible?(user)}.collect(&:id).sort
111 end
130 end
112
131
113 def test_visible_scope_for_anonymous
132 def test_visible_scope_for_anonymous
114 # Anonymous user should see issues of public projects only
133 # Anonymous user should see issues of public projects only
115 issues = Issue.visible(User.anonymous).all
134 issues = Issue.visible(User.anonymous).all
116 assert issues.any?
135 assert issues.any?
117 assert_nil issues.detect {|issue| !issue.project.is_public?}
136 assert_nil issues.detect {|issue| !issue.project.is_public?}
118 assert_nil issues.detect {|issue| issue.is_private?}
137 assert_nil issues.detect {|issue| issue.is_private?}
119 assert_visibility_match User.anonymous, issues
138 assert_visibility_match User.anonymous, issues
120 end
139 end
121
140
122 def test_visible_scope_for_anonymous_without_view_issues_permissions
141 def test_visible_scope_for_anonymous_without_view_issues_permissions
123 # Anonymous user should not see issues without permission
142 # Anonymous user should not see issues without permission
124 Role.anonymous.remove_permission!(:view_issues)
143 Role.anonymous.remove_permission!(:view_issues)
125 issues = Issue.visible(User.anonymous).all
144 issues = Issue.visible(User.anonymous).all
126 assert issues.empty?
145 assert issues.empty?
127 assert_visibility_match User.anonymous, issues
146 assert_visibility_match User.anonymous, issues
128 end
147 end
129
148
130 def test_anonymous_should_not_see_private_issues_with_issues_visibility_set_to_default
149 def test_anonymous_should_not_see_private_issues_with_issues_visibility_set_to_default
131 assert Role.anonymous.update_attribute(:issues_visibility, 'default')
150 assert Role.anonymous.update_attribute(:issues_visibility, 'default')
132 issue = Issue.generate!(:author => User.anonymous, :assigned_to => User.anonymous, :is_private => true)
151 issue = Issue.generate!(:author => User.anonymous, :assigned_to => User.anonymous, :is_private => true)
133 assert_nil Issue.where(:id => issue.id).visible(User.anonymous).first
152 assert_nil Issue.where(:id => issue.id).visible(User.anonymous).first
134 assert !issue.visible?(User.anonymous)
153 assert !issue.visible?(User.anonymous)
135 end
154 end
136
155
137 def test_anonymous_should_not_see_private_issues_with_issues_visibility_set_to_own
156 def test_anonymous_should_not_see_private_issues_with_issues_visibility_set_to_own
138 assert Role.anonymous.update_attribute(:issues_visibility, 'own')
157 assert Role.anonymous.update_attribute(:issues_visibility, 'own')
139 issue = Issue.generate!(:author => User.anonymous, :assigned_to => User.anonymous, :is_private => true)
158 issue = Issue.generate!(:author => User.anonymous, :assigned_to => User.anonymous, :is_private => true)
140 assert_nil Issue.where(:id => issue.id).visible(User.anonymous).first
159 assert_nil Issue.where(:id => issue.id).visible(User.anonymous).first
141 assert !issue.visible?(User.anonymous)
160 assert !issue.visible?(User.anonymous)
142 end
161 end
143
162
144 def test_visible_scope_for_non_member
163 def test_visible_scope_for_non_member
145 user = User.find(9)
164 user = User.find(9)
146 assert user.projects.empty?
165 assert user.projects.empty?
147 # Non member user should see issues of public projects only
166 # Non member user should see issues of public projects only
148 issues = Issue.visible(user).all
167 issues = Issue.visible(user).all
149 assert issues.any?
168 assert issues.any?
150 assert_nil issues.detect {|issue| !issue.project.is_public?}
169 assert_nil issues.detect {|issue| !issue.project.is_public?}
151 assert_nil issues.detect {|issue| issue.is_private?}
170 assert_nil issues.detect {|issue| issue.is_private?}
152 assert_visibility_match user, issues
171 assert_visibility_match user, issues
153 end
172 end
154
173
155 def test_visible_scope_for_non_member_with_own_issues_visibility
174 def test_visible_scope_for_non_member_with_own_issues_visibility
156 Role.non_member.update_attribute :issues_visibility, 'own'
175 Role.non_member.update_attribute :issues_visibility, 'own'
157 Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member')
176 Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 9, :subject => 'Issue by non member')
158 user = User.find(9)
177 user = User.find(9)
159
178
160 issues = Issue.visible(user).all
179 issues = Issue.visible(user).all
161 assert issues.any?
180 assert issues.any?
162 assert_nil issues.detect {|issue| issue.author != user}
181 assert_nil issues.detect {|issue| issue.author != user}
163 assert_visibility_match user, issues
182 assert_visibility_match user, issues
164 end
183 end
165
184
166 def test_visible_scope_for_non_member_without_view_issues_permissions
185 def test_visible_scope_for_non_member_without_view_issues_permissions
167 # Non member user should not see issues without permission
186 # Non member user should not see issues without permission
168 Role.non_member.remove_permission!(:view_issues)
187 Role.non_member.remove_permission!(:view_issues)
169 user = User.find(9)
188 user = User.find(9)
170 assert user.projects.empty?
189 assert user.projects.empty?
171 issues = Issue.visible(user).all
190 issues = Issue.visible(user).all
172 assert issues.empty?
191 assert issues.empty?
173 assert_visibility_match user, issues
192 assert_visibility_match user, issues
174 end
193 end
175
194
176 def test_visible_scope_for_member
195 def test_visible_scope_for_member
177 user = User.find(9)
196 user = User.find(9)
178 # User should see issues of projects for which he has view_issues permissions only
197 # User should see issues of projects for which he has view_issues permissions only
179 Role.non_member.remove_permission!(:view_issues)
198 Role.non_member.remove_permission!(:view_issues)
180 Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
199 Member.create!(:principal => user, :project_id => 3, :role_ids => [2])
181 issues = Issue.visible(user).all
200 issues = Issue.visible(user).all
182 assert issues.any?
201 assert issues.any?
183 assert_nil issues.detect {|issue| issue.project_id != 3}
202 assert_nil issues.detect {|issue| issue.project_id != 3}
184 assert_nil issues.detect {|issue| issue.is_private?}
203 assert_nil issues.detect {|issue| issue.is_private?}
185 assert_visibility_match user, issues
204 assert_visibility_match user, issues
186 end
205 end
187
206
188 def test_visible_scope_for_member_with_groups_should_return_assigned_issues
207 def test_visible_scope_for_member_with_groups_should_return_assigned_issues
189 user = User.find(8)
208 user = User.find(8)
190 assert user.groups.any?
209 assert user.groups.any?
191 Member.create!(:principal => user.groups.first, :project_id => 1, :role_ids => [2])
210 Member.create!(:principal => user.groups.first, :project_id => 1, :role_ids => [2])
192 Role.non_member.remove_permission!(:view_issues)
211 Role.non_member.remove_permission!(:view_issues)
193
212
194 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
213 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
195 :status_id => 1, :priority => IssuePriority.all.first,
214 :status_id => 1, :priority => IssuePriority.all.first,
196 :subject => 'Assignment test',
215 :subject => 'Assignment test',
197 :assigned_to => user.groups.first,
216 :assigned_to => user.groups.first,
198 :is_private => true)
217 :is_private => true)
199
218
200 Role.find(2).update_attribute :issues_visibility, 'default'
219 Role.find(2).update_attribute :issues_visibility, 'default'
201 issues = Issue.visible(User.find(8)).all
220 issues = Issue.visible(User.find(8)).all
202 assert issues.any?
221 assert issues.any?
203 assert issues.include?(issue)
222 assert issues.include?(issue)
204
223
205 Role.find(2).update_attribute :issues_visibility, 'own'
224 Role.find(2).update_attribute :issues_visibility, 'own'
206 issues = Issue.visible(User.find(8)).all
225 issues = Issue.visible(User.find(8)).all
207 assert issues.any?
226 assert issues.any?
208 assert issues.include?(issue)
227 assert issues.include?(issue)
209 end
228 end
210
229
211 def test_visible_scope_for_admin
230 def test_visible_scope_for_admin
212 user = User.find(1)
231 user = User.find(1)
213 user.members.each(&:destroy)
232 user.members.each(&:destroy)
214 assert user.projects.empty?
233 assert user.projects.empty?
215 issues = Issue.visible(user).all
234 issues = Issue.visible(user).all
216 assert issues.any?
235 assert issues.any?
217 # Admin should see issues on private projects that he does not belong to
236 # Admin should see issues on private projects that he does not belong to
218 assert issues.detect {|issue| !issue.project.is_public?}
237 assert issues.detect {|issue| !issue.project.is_public?}
219 # Admin should see private issues of other users
238 # Admin should see private issues of other users
220 assert issues.detect {|issue| issue.is_private? && issue.author != user}
239 assert issues.detect {|issue| issue.is_private? && issue.author != user}
221 assert_visibility_match user, issues
240 assert_visibility_match user, issues
222 end
241 end
223
242
224 def test_visible_scope_with_project
243 def test_visible_scope_with_project
225 project = Project.find(1)
244 project = Project.find(1)
226 issues = Issue.visible(User.find(2), :project => project).all
245 issues = Issue.visible(User.find(2), :project => project).all
227 projects = issues.collect(&:project).uniq
246 projects = issues.collect(&:project).uniq
228 assert_equal 1, projects.size
247 assert_equal 1, projects.size
229 assert_equal project, projects.first
248 assert_equal project, projects.first
230 end
249 end
231
250
232 def test_visible_scope_with_project_and_subprojects
251 def test_visible_scope_with_project_and_subprojects
233 project = Project.find(1)
252 project = Project.find(1)
234 issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
253 issues = Issue.visible(User.find(2), :project => project, :with_subprojects => true).all
235 projects = issues.collect(&:project).uniq
254 projects = issues.collect(&:project).uniq
236 assert projects.size > 1
255 assert projects.size > 1
237 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
256 assert_equal [], projects.select {|p| !p.is_or_is_descendant_of?(project)}
238 end
257 end
239
258
240 def test_visible_and_nested_set_scopes
259 def test_visible_and_nested_set_scopes
241 assert_equal 0, Issue.find(1).descendants.visible.all.size
260 assert_equal 0, Issue.find(1).descendants.visible.all.size
242 end
261 end
243
262
244 def test_open_scope
263 def test_open_scope
245 issues = Issue.open.all
264 issues = Issue.open.all
246 assert_nil issues.detect(&:closed?)
265 assert_nil issues.detect(&:closed?)
247 end
266 end
248
267
249 def test_open_scope_with_arg
268 def test_open_scope_with_arg
250 issues = Issue.open(false).all
269 issues = Issue.open(false).all
251 assert_equal issues, issues.select(&:closed?)
270 assert_equal issues, issues.select(&:closed?)
252 end
271 end
253
272
254 def test_errors_full_messages_should_include_custom_fields_errors
273 def test_errors_full_messages_should_include_custom_fields_errors
255 field = IssueCustomField.find_by_name('Database')
274 field = IssueCustomField.find_by_name('Database')
256
275
257 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
276 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1,
258 :status_id => 1, :subject => 'test_create',
277 :status_id => 1, :subject => 'test_create',
259 :description => 'IssueTest#test_create_with_required_custom_field')
278 :description => 'IssueTest#test_create_with_required_custom_field')
260 assert issue.available_custom_fields.include?(field)
279 assert issue.available_custom_fields.include?(field)
261 # Invalid value
280 # Invalid value
262 issue.custom_field_values = { field.id => 'SQLServer' }
281 issue.custom_field_values = { field.id => 'SQLServer' }
263
282
264 assert !issue.valid?
283 assert !issue.valid?
265 assert_equal 1, issue.errors.full_messages.size
284 assert_equal 1, issue.errors.full_messages.size
266 assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}",
285 assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}",
267 issue.errors.full_messages.first
286 issue.errors.full_messages.first
268 end
287 end
269
288
270 def test_update_issue_with_required_custom_field
289 def test_update_issue_with_required_custom_field
271 field = IssueCustomField.find_by_name('Database')
290 field = IssueCustomField.find_by_name('Database')
272 field.update_attribute(:is_required, true)
291 field.update_attribute(:is_required, true)
273
292
274 issue = Issue.find(1)
293 issue = Issue.find(1)
275 assert_nil issue.custom_value_for(field)
294 assert_nil issue.custom_value_for(field)
276 assert issue.available_custom_fields.include?(field)
295 assert issue.available_custom_fields.include?(field)
277 # No change to custom values, issue can be saved
296 # No change to custom values, issue can be saved
278 assert issue.save
297 assert issue.save
279 # Blank value
298 # Blank value
280 issue.custom_field_values = { field.id => '' }
299 issue.custom_field_values = { field.id => '' }
281 assert !issue.save
300 assert !issue.save
282 # Valid value
301 # Valid value
283 issue.custom_field_values = { field.id => 'PostgreSQL' }
302 issue.custom_field_values = { field.id => 'PostgreSQL' }
284 assert issue.save
303 assert issue.save
285 issue.reload
304 issue.reload
286 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
305 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
287 end
306 end
288
307
289 def test_should_not_update_attributes_if_custom_fields_validation_fails
308 def test_should_not_update_attributes_if_custom_fields_validation_fails
290 issue = Issue.find(1)
309 issue = Issue.find(1)
291 field = IssueCustomField.find_by_name('Database')
310 field = IssueCustomField.find_by_name('Database')
292 assert issue.available_custom_fields.include?(field)
311 assert issue.available_custom_fields.include?(field)
293
312
294 issue.custom_field_values = { field.id => 'Invalid' }
313 issue.custom_field_values = { field.id => 'Invalid' }
295 issue.subject = 'Should be not be saved'
314 issue.subject = 'Should be not be saved'
296 assert !issue.save
315 assert !issue.save
297
316
298 issue.reload
317 issue.reload
299 assert_equal "Can't print recipes", issue.subject
318 assert_equal "Can't print recipes", issue.subject
300 end
319 end
301
320
302 def test_should_not_recreate_custom_values_objects_on_update
321 def test_should_not_recreate_custom_values_objects_on_update
303 field = IssueCustomField.find_by_name('Database')
322 field = IssueCustomField.find_by_name('Database')
304
323
305 issue = Issue.find(1)
324 issue = Issue.find(1)
306 issue.custom_field_values = { field.id => 'PostgreSQL' }
325 issue.custom_field_values = { field.id => 'PostgreSQL' }
307 assert issue.save
326 assert issue.save
308 custom_value = issue.custom_value_for(field)
327 custom_value = issue.custom_value_for(field)
309 issue.reload
328 issue.reload
310 issue.custom_field_values = { field.id => 'MySQL' }
329 issue.custom_field_values = { field.id => 'MySQL' }
311 assert issue.save
330 assert issue.save
312 issue.reload
331 issue.reload
313 assert_equal custom_value.id, issue.custom_value_for(field).id
332 assert_equal custom_value.id, issue.custom_value_for(field).id
314 end
333 end
315
334
316 def test_should_not_update_custom_fields_on_changing_tracker_with_different_custom_fields
335 def test_should_not_update_custom_fields_on_changing_tracker_with_different_custom_fields
317 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => 'Test', :custom_field_values => {'2' => 'Test'})
336 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => 'Test', :custom_field_values => {'2' => 'Test'})
318 assert !Tracker.find(2).custom_field_ids.include?(2)
337 assert !Tracker.find(2).custom_field_ids.include?(2)
319
338
320 issue = Issue.find(issue.id)
339 issue = Issue.find(issue.id)
321 issue.attributes = {:tracker_id => 2, :custom_field_values => {'1' => ''}}
340 issue.attributes = {:tracker_id => 2, :custom_field_values => {'1' => ''}}
322
341
323 issue = Issue.find(issue.id)
342 issue = Issue.find(issue.id)
324 custom_value = issue.custom_value_for(2)
343 custom_value = issue.custom_value_for(2)
325 assert_not_nil custom_value
344 assert_not_nil custom_value
326 assert_equal 'Test', custom_value.value
345 assert_equal 'Test', custom_value.value
327 end
346 end
328
347
329 def test_assigning_tracker_id_should_reload_custom_fields_values
348 def test_assigning_tracker_id_should_reload_custom_fields_values
330 issue = Issue.new(:project => Project.find(1))
349 issue = Issue.new(:project => Project.find(1))
331 assert issue.custom_field_values.empty?
350 assert issue.custom_field_values.empty?
332 issue.tracker_id = 1
351 issue.tracker_id = 1
333 assert issue.custom_field_values.any?
352 assert issue.custom_field_values.any?
334 end
353 end
335
354
336 def test_assigning_attributes_should_assign_project_and_tracker_first
355 def test_assigning_attributes_should_assign_project_and_tracker_first
337 seq = sequence('seq')
356 seq = sequence('seq')
338 issue = Issue.new
357 issue = Issue.new
339 issue.expects(:project_id=).in_sequence(seq)
358 issue.expects(:project_id=).in_sequence(seq)
340 issue.expects(:tracker_id=).in_sequence(seq)
359 issue.expects(:tracker_id=).in_sequence(seq)
341 issue.expects(:subject=).in_sequence(seq)
360 issue.expects(:subject=).in_sequence(seq)
342 issue.attributes = {:tracker_id => 2, :project_id => 1, :subject => 'Test'}
361 issue.attributes = {:tracker_id => 2, :project_id => 1, :subject => 'Test'}
343 end
362 end
344
363
345 def test_assigning_tracker_and_custom_fields_should_assign_custom_fields
364 def test_assigning_tracker_and_custom_fields_should_assign_custom_fields
346 attributes = ActiveSupport::OrderedHash.new
365 attributes = ActiveSupport::OrderedHash.new
347 attributes['custom_field_values'] = { '1' => 'MySQL' }
366 attributes['custom_field_values'] = { '1' => 'MySQL' }
348 attributes['tracker_id'] = '1'
367 attributes['tracker_id'] = '1'
349 issue = Issue.new(:project => Project.find(1))
368 issue = Issue.new(:project => Project.find(1))
350 issue.attributes = attributes
369 issue.attributes = attributes
351 assert_equal 'MySQL', issue.custom_field_value(1)
370 assert_equal 'MySQL', issue.custom_field_value(1)
352 end
371 end
353
372
354 def test_should_update_issue_with_disabled_tracker
373 def test_should_update_issue_with_disabled_tracker
355 p = Project.find(1)
374 p = Project.find(1)
356 issue = Issue.find(1)
375 issue = Issue.find(1)
357
376
358 p.trackers.delete(issue.tracker)
377 p.trackers.delete(issue.tracker)
359 assert !p.trackers.include?(issue.tracker)
378 assert !p.trackers.include?(issue.tracker)
360
379
361 issue.reload
380 issue.reload
362 issue.subject = 'New subject'
381 issue.subject = 'New subject'
363 assert issue.save
382 assert issue.save
364 end
383 end
365
384
366 def test_should_not_set_a_disabled_tracker
385 def test_should_not_set_a_disabled_tracker
367 p = Project.find(1)
386 p = Project.find(1)
368 p.trackers.delete(Tracker.find(2))
387 p.trackers.delete(Tracker.find(2))
369
388
370 issue = Issue.find(1)
389 issue = Issue.find(1)
371 issue.tracker_id = 2
390 issue.tracker_id = 2
372 issue.subject = 'New subject'
391 issue.subject = 'New subject'
373 assert !issue.save
392 assert !issue.save
374 assert_not_nil issue.errors[:tracker_id]
393 assert_not_nil issue.errors[:tracker_id]
375 end
394 end
376
395
377 def test_category_based_assignment
396 def test_category_based_assignment
378 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
397 issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3,
379 :status_id => 1, :priority => IssuePriority.all.first,
398 :status_id => 1, :priority => IssuePriority.all.first,
380 :subject => 'Assignment test',
399 :subject => 'Assignment test',
381 :description => 'Assignment test', :category_id => 1)
400 :description => 'Assignment test', :category_id => 1)
382 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
401 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
383 end
402 end
384
403
385 def test_new_statuses_allowed_to
404 def test_new_statuses_allowed_to
386 WorkflowTransition.delete_all
405 WorkflowTransition.delete_all
387
406
388 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
407 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
389 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
408 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
390 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
409 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
391 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
410 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
392 status = IssueStatus.find(1)
411 status = IssueStatus.find(1)
393 role = Role.find(1)
412 role = Role.find(1)
394 tracker = Tracker.find(1)
413 tracker = Tracker.find(1)
395 user = User.find(2)
414 user = User.find(2)
396
415
397 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author_id => 1)
416 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author_id => 1)
398 assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id)
417 assert_equal [1, 2], issue.new_statuses_allowed_to(user).map(&:id)
399
418
400 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user)
419 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user)
401 assert_equal [1, 2, 3, 5], issue.new_statuses_allowed_to(user).map(&:id)
420 assert_equal [1, 2, 3, 5], issue.new_statuses_allowed_to(user).map(&:id)
402
421
403 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author_id => 1, :assigned_to => user)
422 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author_id => 1, :assigned_to => user)
404 assert_equal [1, 2, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
423 assert_equal [1, 2, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
405
424
406 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user, :assigned_to => user)
425 issue = Issue.generate!(:tracker => tracker, :status => status, :project_id => 1, :author => user, :assigned_to => user)
407 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
426 assert_equal [1, 2, 3, 4, 5], issue.new_statuses_allowed_to(user).map(&:id)
408 end
427 end
409
428
410 def test_new_statuses_allowed_to_should_return_all_transitions_for_admin
429 def test_new_statuses_allowed_to_should_return_all_transitions_for_admin
411 admin = User.find(1)
430 admin = User.find(1)
412 issue = Issue.find(1)
431 issue = Issue.find(1)
413 assert !admin.member_of?(issue.project)
432 assert !admin.member_of?(issue.project)
414 expected_statuses = [issue.status] + WorkflowTransition.find_all_by_old_status_id(issue.status_id).map(&:new_status).uniq.sort
433 expected_statuses = [issue.status] + WorkflowTransition.find_all_by_old_status_id(issue.status_id).map(&:new_status).uniq.sort
415
434
416 assert_equal expected_statuses, issue.new_statuses_allowed_to(admin)
435 assert_equal expected_statuses, issue.new_statuses_allowed_to(admin)
417 end
436 end
418
437
419 def test_new_statuses_allowed_to_should_return_default_and_current_status_when_copying
438 def test_new_statuses_allowed_to_should_return_default_and_current_status_when_copying
420 issue = Issue.find(1).copy
439 issue = Issue.find(1).copy
421 assert_equal [1], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
440 assert_equal [1], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
422
441
423 issue = Issue.find(2).copy
442 issue = Issue.find(2).copy
424 assert_equal [1, 2], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
443 assert_equal [1, 2], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
425 end
444 end
426
445
427 def test_safe_attributes_names_should_not_include_disabled_field
446 def test_safe_attributes_names_should_not_include_disabled_field
428 tracker = Tracker.new(:core_fields => %w(assigned_to_id fixed_version_id))
447 tracker = Tracker.new(:core_fields => %w(assigned_to_id fixed_version_id))
429
448
430 issue = Issue.new(:tracker => tracker)
449 issue = Issue.new(:tracker => tracker)
431 assert_include 'tracker_id', issue.safe_attribute_names
450 assert_include 'tracker_id', issue.safe_attribute_names
432 assert_include 'status_id', issue.safe_attribute_names
451 assert_include 'status_id', issue.safe_attribute_names
433 assert_include 'subject', issue.safe_attribute_names
452 assert_include 'subject', issue.safe_attribute_names
434 assert_include 'description', issue.safe_attribute_names
453 assert_include 'description', issue.safe_attribute_names
435 assert_include 'custom_field_values', issue.safe_attribute_names
454 assert_include 'custom_field_values', issue.safe_attribute_names
436 assert_include 'custom_fields', issue.safe_attribute_names
455 assert_include 'custom_fields', issue.safe_attribute_names
437 assert_include 'lock_version', issue.safe_attribute_names
456 assert_include 'lock_version', issue.safe_attribute_names
438
457
439 tracker.core_fields.each do |field|
458 tracker.core_fields.each do |field|
440 assert_include field, issue.safe_attribute_names
459 assert_include field, issue.safe_attribute_names
441 end
460 end
442
461
443 tracker.disabled_core_fields.each do |field|
462 tracker.disabled_core_fields.each do |field|
444 assert_not_include field, issue.safe_attribute_names
463 assert_not_include field, issue.safe_attribute_names
445 end
464 end
446 end
465 end
447
466
448 def test_safe_attributes_should_ignore_disabled_fields
467 def test_safe_attributes_should_ignore_disabled_fields
449 tracker = Tracker.find(1)
468 tracker = Tracker.find(1)
450 tracker.core_fields = %w(assigned_to_id due_date)
469 tracker.core_fields = %w(assigned_to_id due_date)
451 tracker.save!
470 tracker.save!
452
471
453 issue = Issue.new(:tracker => tracker)
472 issue = Issue.new(:tracker => tracker)
454 issue.safe_attributes = {'start_date' => '2012-07-14', 'due_date' => '2012-07-14'}
473 issue.safe_attributes = {'start_date' => '2012-07-14', 'due_date' => '2012-07-14'}
455 assert_nil issue.start_date
474 assert_nil issue.start_date
456 assert_equal Date.parse('2012-07-14'), issue.due_date
475 assert_equal Date.parse('2012-07-14'), issue.due_date
457 end
476 end
458
477
459 def test_safe_attributes_should_accept_target_tracker_enabled_fields
478 def test_safe_attributes_should_accept_target_tracker_enabled_fields
460 source = Tracker.find(1)
479 source = Tracker.find(1)
461 source.core_fields = []
480 source.core_fields = []
462 source.save!
481 source.save!
463 target = Tracker.find(2)
482 target = Tracker.find(2)
464 target.core_fields = %w(assigned_to_id due_date)
483 target.core_fields = %w(assigned_to_id due_date)
465 target.save!
484 target.save!
466
485
467 issue = Issue.new(:tracker => source)
486 issue = Issue.new(:tracker => source)
468 issue.safe_attributes = {'tracker_id' => 2, 'due_date' => '2012-07-14'}
487 issue.safe_attributes = {'tracker_id' => 2, 'due_date' => '2012-07-14'}
469 assert_equal target, issue.tracker
488 assert_equal target, issue.tracker
470 assert_equal Date.parse('2012-07-14'), issue.due_date
489 assert_equal Date.parse('2012-07-14'), issue.due_date
471 end
490 end
472
491
473 def test_safe_attributes_should_not_include_readonly_fields
492 def test_safe_attributes_should_not_include_readonly_fields
474 WorkflowPermission.delete_all
493 WorkflowPermission.delete_all
475 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
494 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
476 user = User.find(2)
495 user = User.find(2)
477
496
478 issue = Issue.new(:project_id => 1, :tracker_id => 1)
497 issue = Issue.new(:project_id => 1, :tracker_id => 1)
479 assert_equal %w(due_date), issue.read_only_attribute_names(user)
498 assert_equal %w(due_date), issue.read_only_attribute_names(user)
480 assert_not_include 'due_date', issue.safe_attribute_names(user)
499 assert_not_include 'due_date', issue.safe_attribute_names(user)
481
500
482 issue.send :safe_attributes=, {'start_date' => '2012-07-14', 'due_date' => '2012-07-14'}, user
501 issue.send :safe_attributes=, {'start_date' => '2012-07-14', 'due_date' => '2012-07-14'}, user
483 assert_equal Date.parse('2012-07-14'), issue.start_date
502 assert_equal Date.parse('2012-07-14'), issue.start_date
484 assert_nil issue.due_date
503 assert_nil issue.due_date
485 end
504 end
486
505
487 def test_safe_attributes_should_not_include_readonly_custom_fields
506 def test_safe_attributes_should_not_include_readonly_custom_fields
488 cf1 = IssueCustomField.create!(:name => 'Writable field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1])
507 cf1 = IssueCustomField.create!(:name => 'Writable field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1])
489 cf2 = IssueCustomField.create!(:name => 'Readonly field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1])
508 cf2 = IssueCustomField.create!(:name => 'Readonly field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1])
490
509
491 WorkflowPermission.delete_all
510 WorkflowPermission.delete_all
492 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
511 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
493 user = User.find(2)
512 user = User.find(2)
494
513
495 issue = Issue.new(:project_id => 1, :tracker_id => 1)
514 issue = Issue.new(:project_id => 1, :tracker_id => 1)
496 assert_equal [cf2.id.to_s], issue.read_only_attribute_names(user)
515 assert_equal [cf2.id.to_s], issue.read_only_attribute_names(user)
497 assert_not_include cf2.id.to_s, issue.safe_attribute_names(user)
516 assert_not_include cf2.id.to_s, issue.safe_attribute_names(user)
498
517
499 issue.send :safe_attributes=, {'custom_field_values' => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}}, user
518 issue.send :safe_attributes=, {'custom_field_values' => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}}, user
500 assert_equal 'value1', issue.custom_field_value(cf1)
519 assert_equal 'value1', issue.custom_field_value(cf1)
501 assert_nil issue.custom_field_value(cf2)
520 assert_nil issue.custom_field_value(cf2)
502
521
503 issue.send :safe_attributes=, {'custom_fields' => [{'id' => cf1.id.to_s, 'value' => 'valuea'}, {'id' => cf2.id.to_s, 'value' => 'valueb'}]}, user
522 issue.send :safe_attributes=, {'custom_fields' => [{'id' => cf1.id.to_s, 'value' => 'valuea'}, {'id' => cf2.id.to_s, 'value' => 'valueb'}]}, user
504 assert_equal 'valuea', issue.custom_field_value(cf1)
523 assert_equal 'valuea', issue.custom_field_value(cf1)
505 assert_nil issue.custom_field_value(cf2)
524 assert_nil issue.custom_field_value(cf2)
506 end
525 end
507
526
508 def test_editable_custom_field_values_should_return_non_readonly_custom_values
527 def test_editable_custom_field_values_should_return_non_readonly_custom_values
509 cf1 = IssueCustomField.create!(:name => 'Writable field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
528 cf1 = IssueCustomField.create!(:name => 'Writable field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
510 cf2 = IssueCustomField.create!(:name => 'Readonly field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
529 cf2 = IssueCustomField.create!(:name => 'Readonly field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
511
530
512 WorkflowPermission.delete_all
531 WorkflowPermission.delete_all
513 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
532 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
514 user = User.find(2)
533 user = User.find(2)
515
534
516 issue = Issue.new(:project_id => 1, :tracker_id => 1)
535 issue = Issue.new(:project_id => 1, :tracker_id => 1)
517 values = issue.editable_custom_field_values(user)
536 values = issue.editable_custom_field_values(user)
518 assert values.detect {|value| value.custom_field == cf1}
537 assert values.detect {|value| value.custom_field == cf1}
519 assert_nil values.detect {|value| value.custom_field == cf2}
538 assert_nil values.detect {|value| value.custom_field == cf2}
520
539
521 issue.tracker_id = 2
540 issue.tracker_id = 2
522 values = issue.editable_custom_field_values(user)
541 values = issue.editable_custom_field_values(user)
523 assert values.detect {|value| value.custom_field == cf1}
542 assert values.detect {|value| value.custom_field == cf1}
524 assert values.detect {|value| value.custom_field == cf2}
543 assert values.detect {|value| value.custom_field == cf2}
525 end
544 end
526
545
527 def test_safe_attributes_should_accept_target_tracker_writable_fields
546 def test_safe_attributes_should_accept_target_tracker_writable_fields
528 WorkflowPermission.delete_all
547 WorkflowPermission.delete_all
529 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
548 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
530 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
549 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
531 user = User.find(2)
550 user = User.find(2)
532
551
533 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
552 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
534
553
535 issue.send :safe_attributes=, {'start_date' => '2012-07-12', 'due_date' => '2012-07-14'}, user
554 issue.send :safe_attributes=, {'start_date' => '2012-07-12', 'due_date' => '2012-07-14'}, user
536 assert_equal Date.parse('2012-07-12'), issue.start_date
555 assert_equal Date.parse('2012-07-12'), issue.start_date
537 assert_nil issue.due_date
556 assert_nil issue.due_date
538
557
539 issue.send :safe_attributes=, {'start_date' => '2012-07-15', 'due_date' => '2012-07-16', 'tracker_id' => 2}, user
558 issue.send :safe_attributes=, {'start_date' => '2012-07-15', 'due_date' => '2012-07-16', 'tracker_id' => 2}, user
540 assert_equal Date.parse('2012-07-12'), issue.start_date
559 assert_equal Date.parse('2012-07-12'), issue.start_date
541 assert_equal Date.parse('2012-07-16'), issue.due_date
560 assert_equal Date.parse('2012-07-16'), issue.due_date
542 end
561 end
543
562
544 def test_safe_attributes_should_accept_target_status_writable_fields
563 def test_safe_attributes_should_accept_target_status_writable_fields
545 WorkflowPermission.delete_all
564 WorkflowPermission.delete_all
546 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
565 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
547 WorkflowPermission.create!(:old_status_id => 2, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
566 WorkflowPermission.create!(:old_status_id => 2, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
548 user = User.find(2)
567 user = User.find(2)
549
568
550 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
569 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
551
570
552 issue.send :safe_attributes=, {'start_date' => '2012-07-12', 'due_date' => '2012-07-14'}, user
571 issue.send :safe_attributes=, {'start_date' => '2012-07-12', 'due_date' => '2012-07-14'}, user
553 assert_equal Date.parse('2012-07-12'), issue.start_date
572 assert_equal Date.parse('2012-07-12'), issue.start_date
554 assert_nil issue.due_date
573 assert_nil issue.due_date
555
574
556 issue.send :safe_attributes=, {'start_date' => '2012-07-15', 'due_date' => '2012-07-16', 'status_id' => 2}, user
575 issue.send :safe_attributes=, {'start_date' => '2012-07-15', 'due_date' => '2012-07-16', 'status_id' => 2}, user
557 assert_equal Date.parse('2012-07-12'), issue.start_date
576 assert_equal Date.parse('2012-07-12'), issue.start_date
558 assert_equal Date.parse('2012-07-16'), issue.due_date
577 assert_equal Date.parse('2012-07-16'), issue.due_date
559 end
578 end
560
579
561 def test_required_attributes_should_be_validated
580 def test_required_attributes_should_be_validated
562 cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
581 cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
563
582
564 WorkflowPermission.delete_all
583 WorkflowPermission.delete_all
565 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
584 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
566 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'category_id', :rule => 'required')
585 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'category_id', :rule => 'required')
567 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf.id.to_s, :rule => 'required')
586 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf.id.to_s, :rule => 'required')
568
587
569 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'start_date', :rule => 'required')
588 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'start_date', :rule => 'required')
570 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf.id.to_s, :rule => 'required')
589 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf.id.to_s, :rule => 'required')
571 user = User.find(2)
590 user = User.find(2)
572
591
573 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Required fields', :author => user)
592 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Required fields', :author => user)
574 assert_equal [cf.id.to_s, "category_id", "due_date"], issue.required_attribute_names(user).sort
593 assert_equal [cf.id.to_s, "category_id", "due_date"], issue.required_attribute_names(user).sort
575 assert !issue.save, "Issue was saved"
594 assert !issue.save, "Issue was saved"
576 assert_equal ["Category can't be blank", "Due date can't be blank", "Foo can't be blank"], issue.errors.full_messages.sort
595 assert_equal ["Category can't be blank", "Due date can't be blank", "Foo can't be blank"], issue.errors.full_messages.sort
577
596
578 issue.tracker_id = 2
597 issue.tracker_id = 2
579 assert_equal [cf.id.to_s, "start_date"], issue.required_attribute_names(user).sort
598 assert_equal [cf.id.to_s, "start_date"], issue.required_attribute_names(user).sort
580 assert !issue.save, "Issue was saved"
599 assert !issue.save, "Issue was saved"
581 assert_equal ["Foo can't be blank", "Start date can't be blank"], issue.errors.full_messages.sort
600 assert_equal ["Foo can't be blank", "Start date can't be blank"], issue.errors.full_messages.sort
582
601
583 issue.start_date = Date.today
602 issue.start_date = Date.today
584 issue.custom_field_values = {cf.id.to_s => 'bar'}
603 issue.custom_field_values = {cf.id.to_s => 'bar'}
585 assert issue.save
604 assert issue.save
586 end
605 end
587
606
588 def test_required_attribute_names_for_multiple_roles_should_intersect_rules
607 def test_required_attribute_names_for_multiple_roles_should_intersect_rules
589 WorkflowPermission.delete_all
608 WorkflowPermission.delete_all
590 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
609 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
591 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'required')
610 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'required')
592 user = User.find(2)
611 user = User.find(2)
593 member = Member.find(1)
612 member = Member.find(1)
594 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
613 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
595
614
596 assert_equal %w(due_date start_date), issue.required_attribute_names(user).sort
615 assert_equal %w(due_date start_date), issue.required_attribute_names(user).sort
597
616
598 member.role_ids = [1, 2]
617 member.role_ids = [1, 2]
599 member.save!
618 member.save!
600 assert_equal [], issue.required_attribute_names(user.reload)
619 assert_equal [], issue.required_attribute_names(user.reload)
601
620
602 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'required')
621 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'required')
603 assert_equal %w(due_date), issue.required_attribute_names(user)
622 assert_equal %w(due_date), issue.required_attribute_names(user)
604
623
605 member.role_ids = [1, 2, 3]
624 member.role_ids = [1, 2, 3]
606 member.save!
625 member.save!
607 assert_equal [], issue.required_attribute_names(user.reload)
626 assert_equal [], issue.required_attribute_names(user.reload)
608
627
609 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'readonly')
628 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'readonly')
610 # required + readonly => required
629 # required + readonly => required
611 assert_equal %w(due_date), issue.required_attribute_names(user)
630 assert_equal %w(due_date), issue.required_attribute_names(user)
612 end
631 end
613
632
614 def test_read_only_attribute_names_for_multiple_roles_should_intersect_rules
633 def test_read_only_attribute_names_for_multiple_roles_should_intersect_rules
615 WorkflowPermission.delete_all
634 WorkflowPermission.delete_all
616 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
635 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
617 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
636 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
618 user = User.find(2)
637 user = User.find(2)
619 member = Member.find(1)
638 member = Member.find(1)
620 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
639 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
621
640
622 assert_equal %w(due_date start_date), issue.read_only_attribute_names(user).sort
641 assert_equal %w(due_date start_date), issue.read_only_attribute_names(user).sort
623
642
624 member.role_ids = [1, 2]
643 member.role_ids = [1, 2]
625 member.save!
644 member.save!
626 assert_equal [], issue.read_only_attribute_names(user.reload)
645 assert_equal [], issue.read_only_attribute_names(user.reload)
627
646
628 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'readonly')
647 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'readonly')
629 assert_equal %w(due_date), issue.read_only_attribute_names(user)
648 assert_equal %w(due_date), issue.read_only_attribute_names(user)
630 end
649 end
631
650
632 def test_copy
651 def test_copy
633 issue = Issue.new.copy_from(1)
652 issue = Issue.new.copy_from(1)
634 assert issue.copy?
653 assert issue.copy?
635 assert issue.save
654 assert issue.save
636 issue.reload
655 issue.reload
637 orig = Issue.find(1)
656 orig = Issue.find(1)
638 assert_equal orig.subject, issue.subject
657 assert_equal orig.subject, issue.subject
639 assert_equal orig.tracker, issue.tracker
658 assert_equal orig.tracker, issue.tracker
640 assert_equal "125", issue.custom_value_for(2).value
659 assert_equal "125", issue.custom_value_for(2).value
641 end
660 end
642
661
643 def test_copy_should_copy_status
662 def test_copy_should_copy_status
644 orig = Issue.find(8)
663 orig = Issue.find(8)
645 assert orig.status != IssueStatus.default
664 assert orig.status != IssueStatus.default
646
665
647 issue = Issue.new.copy_from(orig)
666 issue = Issue.new.copy_from(orig)
648 assert issue.save
667 assert issue.save
649 issue.reload
668 issue.reload
650 assert_equal orig.status, issue.status
669 assert_equal orig.status, issue.status
651 end
670 end
652
671
653 def test_copy_should_add_relation_with_copied_issue
672 def test_copy_should_add_relation_with_copied_issue
654 copied = Issue.find(1)
673 copied = Issue.find(1)
655 issue = Issue.new.copy_from(copied)
674 issue = Issue.new.copy_from(copied)
656 assert issue.save
675 assert issue.save
657 issue.reload
676 issue.reload
658
677
659 assert_equal 1, issue.relations.size
678 assert_equal 1, issue.relations.size
660 relation = issue.relations.first
679 relation = issue.relations.first
661 assert_equal 'copied_to', relation.relation_type
680 assert_equal 'copied_to', relation.relation_type
662 assert_equal copied, relation.issue_from
681 assert_equal copied, relation.issue_from
663 assert_equal issue, relation.issue_to
682 assert_equal issue, relation.issue_to
664 end
683 end
665
684
666 def test_copy_should_copy_subtasks
685 def test_copy_should_copy_subtasks
667 issue = Issue.generate_with_descendants!
686 issue = Issue.generate_with_descendants!
668
687
669 copy = issue.reload.copy
688 copy = issue.reload.copy
670 copy.author = User.find(7)
689 copy.author = User.find(7)
671 assert_difference 'Issue.count', 1+issue.descendants.count do
690 assert_difference 'Issue.count', 1+issue.descendants.count do
672 assert copy.save
691 assert copy.save
673 end
692 end
674 copy.reload
693 copy.reload
675 assert_equal %w(Child1 Child2), copy.children.map(&:subject).sort
694 assert_equal %w(Child1 Child2), copy.children.map(&:subject).sort
676 child_copy = copy.children.detect {|c| c.subject == 'Child1'}
695 child_copy = copy.children.detect {|c| c.subject == 'Child1'}
677 assert_equal %w(Child11), child_copy.children.map(&:subject).sort
696 assert_equal %w(Child11), child_copy.children.map(&:subject).sort
678 assert_equal copy.author, child_copy.author
697 assert_equal copy.author, child_copy.author
679 end
698 end
680
699
681 def test_copy_should_copy_subtasks_to_target_project
700 def test_copy_should_copy_subtasks_to_target_project
682 issue = Issue.generate_with_descendants!
701 issue = Issue.generate_with_descendants!
683
702
684 copy = issue.copy(:project_id => 3)
703 copy = issue.copy(:project_id => 3)
685 assert_difference 'Issue.count', 1+issue.descendants.count do
704 assert_difference 'Issue.count', 1+issue.descendants.count do
686 assert copy.save
705 assert copy.save
687 end
706 end
688 assert_equal [3], copy.reload.descendants.map(&:project_id).uniq
707 assert_equal [3], copy.reload.descendants.map(&:project_id).uniq
689 end
708 end
690
709
691 def test_copy_should_not_copy_subtasks_twice_when_saving_twice
710 def test_copy_should_not_copy_subtasks_twice_when_saving_twice
692 issue = Issue.generate_with_descendants!
711 issue = Issue.generate_with_descendants!
693
712
694 copy = issue.reload.copy
713 copy = issue.reload.copy
695 assert_difference 'Issue.count', 1+issue.descendants.count do
714 assert_difference 'Issue.count', 1+issue.descendants.count do
696 assert copy.save
715 assert copy.save
697 assert copy.save
716 assert copy.save
698 end
717 end
699 end
718 end
700
719
701 def test_should_not_call_after_project_change_on_creation
720 def test_should_not_call_after_project_change_on_creation
702 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Test', :author_id => 1)
721 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Test', :author_id => 1)
703 issue.expects(:after_project_change).never
722 issue.expects(:after_project_change).never
704 issue.save!
723 issue.save!
705 end
724 end
706
725
707 def test_should_not_call_after_project_change_on_update
726 def test_should_not_call_after_project_change_on_update
708 issue = Issue.find(1)
727 issue = Issue.find(1)
709 issue.project = Project.find(1)
728 issue.project = Project.find(1)
710 issue.subject = 'No project change'
729 issue.subject = 'No project change'
711 issue.expects(:after_project_change).never
730 issue.expects(:after_project_change).never
712 issue.save!
731 issue.save!
713 end
732 end
714
733
715 def test_should_call_after_project_change_on_project_change
734 def test_should_call_after_project_change_on_project_change
716 issue = Issue.find(1)
735 issue = Issue.find(1)
717 issue.project = Project.find(2)
736 issue.project = Project.find(2)
718 issue.expects(:after_project_change).once
737 issue.expects(:after_project_change).once
719 issue.save!
738 issue.save!
720 end
739 end
721
740
722 def test_adding_journal_should_update_timestamp
741 def test_adding_journal_should_update_timestamp
723 issue = Issue.find(1)
742 issue = Issue.find(1)
724 updated_on_was = issue.updated_on
743 updated_on_was = issue.updated_on
725
744
726 issue.init_journal(User.first, "Adding notes")
745 issue.init_journal(User.first, "Adding notes")
727 assert_difference 'Journal.count' do
746 assert_difference 'Journal.count' do
728 assert issue.save
747 assert issue.save
729 end
748 end
730 issue.reload
749 issue.reload
731
750
732 assert_not_equal updated_on_was, issue.updated_on
751 assert_not_equal updated_on_was, issue.updated_on
733 end
752 end
734
753
735 def test_should_close_duplicates
754 def test_should_close_duplicates
736 # Create 3 issues
755 # Create 3 issues
737 issue1 = Issue.generate!
756 issue1 = Issue.generate!
738 issue2 = Issue.generate!
757 issue2 = Issue.generate!
739 issue3 = Issue.generate!
758 issue3 = Issue.generate!
740
759
741 # 2 is a dupe of 1
760 # 2 is a dupe of 1
742 IssueRelation.create!(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
761 IssueRelation.create!(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
743 # And 3 is a dupe of 2
762 # And 3 is a dupe of 2
744 IssueRelation.create!(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
763 IssueRelation.create!(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
745 # And 3 is a dupe of 1 (circular duplicates)
764 # And 3 is a dupe of 1 (circular duplicates)
746 IssueRelation.create!(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
765 IssueRelation.create!(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
747
766
748 assert issue1.reload.duplicates.include?(issue2)
767 assert issue1.reload.duplicates.include?(issue2)
749
768
750 # Closing issue 1
769 # Closing issue 1
751 issue1.init_journal(User.find(:first), "Closing issue1")
770 issue1.init_journal(User.find(:first), "Closing issue1")
752 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
771 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
753 assert issue1.save
772 assert issue1.save
754 # 2 and 3 should be also closed
773 # 2 and 3 should be also closed
755 assert issue2.reload.closed?
774 assert issue2.reload.closed?
756 assert issue3.reload.closed?
775 assert issue3.reload.closed?
757 end
776 end
758
777
759 def test_should_not_close_duplicated_issue
778 def test_should_not_close_duplicated_issue
760 issue1 = Issue.generate!
779 issue1 = Issue.generate!
761 issue2 = Issue.generate!
780 issue2 = Issue.generate!
762
781
763 # 2 is a dupe of 1
782 # 2 is a dupe of 1
764 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
783 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
765 # 2 is a dup of 1 but 1 is not a duplicate of 2
784 # 2 is a dup of 1 but 1 is not a duplicate of 2
766 assert !issue2.reload.duplicates.include?(issue1)
785 assert !issue2.reload.duplicates.include?(issue1)
767
786
768 # Closing issue 2
787 # Closing issue 2
769 issue2.init_journal(User.find(:first), "Closing issue2")
788 issue2.init_journal(User.find(:first), "Closing issue2")
770 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
789 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
771 assert issue2.save
790 assert issue2.save
772 # 1 should not be also closed
791 # 1 should not be also closed
773 assert !issue1.reload.closed?
792 assert !issue1.reload.closed?
774 end
793 end
775
794
776 def test_assignable_versions
795 def test_assignable_versions
777 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
796 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
778 assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
797 assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
779 end
798 end
780
799
781 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
800 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
782 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
801 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
783 assert !issue.save
802 assert !issue.save
784 assert_not_nil issue.errors[:fixed_version_id]
803 assert_not_nil issue.errors[:fixed_version_id]
785 end
804 end
786
805
787 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
806 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
788 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
807 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
789 assert !issue.save
808 assert !issue.save
790 assert_not_nil issue.errors[:fixed_version_id]
809 assert_not_nil issue.errors[:fixed_version_id]
791 end
810 end
792
811
793 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
812 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
794 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
813 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
795 assert issue.save
814 assert issue.save
796 end
815 end
797
816
798 def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
817 def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
799 issue = Issue.find(11)
818 issue = Issue.find(11)
800 assert_equal 'closed', issue.fixed_version.status
819 assert_equal 'closed', issue.fixed_version.status
801 issue.subject = 'Subject changed'
820 issue.subject = 'Subject changed'
802 assert issue.save
821 assert issue.save
803 end
822 end
804
823
805 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
824 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
806 issue = Issue.find(11)
825 issue = Issue.find(11)
807 issue.status_id = 1
826 issue.status_id = 1
808 assert !issue.save
827 assert !issue.save
809 assert_not_nil issue.errors[:base]
828 assert_not_nil issue.errors[:base]
810 end
829 end
811
830
812 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
831 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
813 issue = Issue.find(11)
832 issue = Issue.find(11)
814 issue.status_id = 1
833 issue.status_id = 1
815 issue.fixed_version_id = 3
834 issue.fixed_version_id = 3
816 assert issue.save
835 assert issue.save
817 end
836 end
818
837
819 def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
838 def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
820 issue = Issue.find(12)
839 issue = Issue.find(12)
821 assert_equal 'locked', issue.fixed_version.status
840 assert_equal 'locked', issue.fixed_version.status
822 issue.status_id = 1
841 issue.status_id = 1
823 assert issue.save
842 assert issue.save
824 end
843 end
825
844
826 def test_should_not_be_able_to_keep_unshared_version_when_changing_project
845 def test_should_not_be_able_to_keep_unshared_version_when_changing_project
827 issue = Issue.find(2)
846 issue = Issue.find(2)
828 assert_equal 2, issue.fixed_version_id
847 assert_equal 2, issue.fixed_version_id
829 issue.project_id = 3
848 issue.project_id = 3
830 assert_nil issue.fixed_version_id
849 assert_nil issue.fixed_version_id
831 issue.fixed_version_id = 2
850 issue.fixed_version_id = 2
832 assert !issue.save
851 assert !issue.save
833 assert_include 'Target version is not included in the list', issue.errors.full_messages
852 assert_include 'Target version is not included in the list', issue.errors.full_messages
834 end
853 end
835
854
836 def test_should_keep_shared_version_when_changing_project
855 def test_should_keep_shared_version_when_changing_project
837 Version.find(2).update_attribute :sharing, 'tree'
856 Version.find(2).update_attribute :sharing, 'tree'
838
857
839 issue = Issue.find(2)
858 issue = Issue.find(2)
840 assert_equal 2, issue.fixed_version_id
859 assert_equal 2, issue.fixed_version_id
841 issue.project_id = 3
860 issue.project_id = 3
842 assert_equal 2, issue.fixed_version_id
861 assert_equal 2, issue.fixed_version_id
843 assert issue.save
862 assert issue.save
844 end
863 end
845
864
846 def test_allowed_target_projects_on_move_should_include_projects_with_issue_tracking_enabled
865 def test_allowed_target_projects_on_move_should_include_projects_with_issue_tracking_enabled
847 assert_include Project.find(2), Issue.allowed_target_projects_on_move(User.find(2))
866 assert_include Project.find(2), Issue.allowed_target_projects_on_move(User.find(2))
848 end
867 end
849
868
850 def test_allowed_target_projects_on_move_should_not_include_projects_with_issue_tracking_disabled
869 def test_allowed_target_projects_on_move_should_not_include_projects_with_issue_tracking_disabled
851 Project.find(2).disable_module! :issue_tracking
870 Project.find(2).disable_module! :issue_tracking
852 assert_not_include Project.find(2), Issue.allowed_target_projects_on_move(User.find(2))
871 assert_not_include Project.find(2), Issue.allowed_target_projects_on_move(User.find(2))
853 end
872 end
854
873
855 def test_move_to_another_project_with_same_category
874 def test_move_to_another_project_with_same_category
856 issue = Issue.find(1)
875 issue = Issue.find(1)
857 issue.project = Project.find(2)
876 issue.project = Project.find(2)
858 assert issue.save
877 assert issue.save
859 issue.reload
878 issue.reload
860 assert_equal 2, issue.project_id
879 assert_equal 2, issue.project_id
861 # Category changes
880 # Category changes
862 assert_equal 4, issue.category_id
881 assert_equal 4, issue.category_id
863 # Make sure time entries were move to the target project
882 # Make sure time entries were move to the target project
864 assert_equal 2, issue.time_entries.first.project_id
883 assert_equal 2, issue.time_entries.first.project_id
865 end
884 end
866
885
867 def test_move_to_another_project_without_same_category
886 def test_move_to_another_project_without_same_category
868 issue = Issue.find(2)
887 issue = Issue.find(2)
869 issue.project = Project.find(2)
888 issue.project = Project.find(2)
870 assert issue.save
889 assert issue.save
871 issue.reload
890 issue.reload
872 assert_equal 2, issue.project_id
891 assert_equal 2, issue.project_id
873 # Category cleared
892 # Category cleared
874 assert_nil issue.category_id
893 assert_nil issue.category_id
875 end
894 end
876
895
877 def test_move_to_another_project_should_clear_fixed_version_when_not_shared
896 def test_move_to_another_project_should_clear_fixed_version_when_not_shared
878 issue = Issue.find(1)
897 issue = Issue.find(1)
879 issue.update_attribute(:fixed_version_id, 1)
898 issue.update_attribute(:fixed_version_id, 1)
880 issue.project = Project.find(2)
899 issue.project = Project.find(2)
881 assert issue.save
900 assert issue.save
882 issue.reload
901 issue.reload
883 assert_equal 2, issue.project_id
902 assert_equal 2, issue.project_id
884 # Cleared fixed_version
903 # Cleared fixed_version
885 assert_equal nil, issue.fixed_version
904 assert_equal nil, issue.fixed_version
886 end
905 end
887
906
888 def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
907 def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
889 issue = Issue.find(1)
908 issue = Issue.find(1)
890 issue.update_attribute(:fixed_version_id, 4)
909 issue.update_attribute(:fixed_version_id, 4)
891 issue.project = Project.find(5)
910 issue.project = Project.find(5)
892 assert issue.save
911 assert issue.save
893 issue.reload
912 issue.reload
894 assert_equal 5, issue.project_id
913 assert_equal 5, issue.project_id
895 # Keep fixed_version
914 # Keep fixed_version
896 assert_equal 4, issue.fixed_version_id
915 assert_equal 4, issue.fixed_version_id
897 end
916 end
898
917
899 def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
918 def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
900 issue = Issue.find(1)
919 issue = Issue.find(1)
901 issue.update_attribute(:fixed_version_id, 1)
920 issue.update_attribute(:fixed_version_id, 1)
902 issue.project = Project.find(5)
921 issue.project = Project.find(5)
903 assert issue.save
922 assert issue.save
904 issue.reload
923 issue.reload
905 assert_equal 5, issue.project_id
924 assert_equal 5, issue.project_id
906 # Cleared fixed_version
925 # Cleared fixed_version
907 assert_equal nil, issue.fixed_version
926 assert_equal nil, issue.fixed_version
908 end
927 end
909
928
910 def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
929 def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
911 issue = Issue.find(1)
930 issue = Issue.find(1)
912 issue.update_attribute(:fixed_version_id, 7)
931 issue.update_attribute(:fixed_version_id, 7)
913 issue.project = Project.find(2)
932 issue.project = Project.find(2)
914 assert issue.save
933 assert issue.save
915 issue.reload
934 issue.reload
916 assert_equal 2, issue.project_id
935 assert_equal 2, issue.project_id
917 # Keep fixed_version
936 # Keep fixed_version
918 assert_equal 7, issue.fixed_version_id
937 assert_equal 7, issue.fixed_version_id
919 end
938 end
920
939
921 def test_move_to_another_project_should_keep_parent_if_valid
940 def test_move_to_another_project_should_keep_parent_if_valid
922 issue = Issue.find(1)
941 issue = Issue.find(1)
923 issue.update_attribute(:parent_issue_id, 2)
942 issue.update_attribute(:parent_issue_id, 2)
924 issue.project = Project.find(3)
943 issue.project = Project.find(3)
925 assert issue.save
944 assert issue.save
926 issue.reload
945 issue.reload
927 assert_equal 2, issue.parent_id
946 assert_equal 2, issue.parent_id
928 end
947 end
929
948
930 def test_move_to_another_project_should_clear_parent_if_not_valid
949 def test_move_to_another_project_should_clear_parent_if_not_valid
931 issue = Issue.find(1)
950 issue = Issue.find(1)
932 issue.update_attribute(:parent_issue_id, 2)
951 issue.update_attribute(:parent_issue_id, 2)
933 issue.project = Project.find(2)
952 issue.project = Project.find(2)
934 assert issue.save
953 assert issue.save
935 issue.reload
954 issue.reload
936 assert_nil issue.parent_id
955 assert_nil issue.parent_id
937 end
956 end
938
957
939 def test_move_to_another_project_with_disabled_tracker
958 def test_move_to_another_project_with_disabled_tracker
940 issue = Issue.find(1)
959 issue = Issue.find(1)
941 target = Project.find(2)
960 target = Project.find(2)
942 target.tracker_ids = [3]
961 target.tracker_ids = [3]
943 target.save
962 target.save
944 issue.project = target
963 issue.project = target
945 assert issue.save
964 assert issue.save
946 issue.reload
965 issue.reload
947 assert_equal 2, issue.project_id
966 assert_equal 2, issue.project_id
948 assert_equal 3, issue.tracker_id
967 assert_equal 3, issue.tracker_id
949 end
968 end
950
969
951 def test_copy_to_the_same_project
970 def test_copy_to_the_same_project
952 issue = Issue.find(1)
971 issue = Issue.find(1)
953 copy = issue.copy
972 copy = issue.copy
954 assert_difference 'Issue.count' do
973 assert_difference 'Issue.count' do
955 copy.save!
974 copy.save!
956 end
975 end
957 assert_kind_of Issue, copy
976 assert_kind_of Issue, copy
958 assert_equal issue.project, copy.project
977 assert_equal issue.project, copy.project
959 assert_equal "125", copy.custom_value_for(2).value
978 assert_equal "125", copy.custom_value_for(2).value
960 end
979 end
961
980
962 def test_copy_to_another_project_and_tracker
981 def test_copy_to_another_project_and_tracker
963 issue = Issue.find(1)
982 issue = Issue.find(1)
964 copy = issue.copy(:project_id => 3, :tracker_id => 2)
983 copy = issue.copy(:project_id => 3, :tracker_id => 2)
965 assert_difference 'Issue.count' do
984 assert_difference 'Issue.count' do
966 copy.save!
985 copy.save!
967 end
986 end
968 copy.reload
987 copy.reload
969 assert_kind_of Issue, copy
988 assert_kind_of Issue, copy
970 assert_equal Project.find(3), copy.project
989 assert_equal Project.find(3), copy.project
971 assert_equal Tracker.find(2), copy.tracker
990 assert_equal Tracker.find(2), copy.tracker
972 # Custom field #2 is not associated with target tracker
991 # Custom field #2 is not associated with target tracker
973 assert_nil copy.custom_value_for(2)
992 assert_nil copy.custom_value_for(2)
974 end
993 end
975
994
976 context "#copy" do
995 context "#copy" do
977 setup do
996 setup do
978 @issue = Issue.find(1)
997 @issue = Issue.find(1)
979 end
998 end
980
999
981 should "not create a journal" do
1000 should "not create a journal" do
982 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
1001 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
983 copy.save!
1002 copy.save!
984 assert_equal 0, copy.reload.journals.size
1003 assert_equal 0, copy.reload.journals.size
985 end
1004 end
986
1005
987 should "allow assigned_to changes" do
1006 should "allow assigned_to changes" do
988 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
1007 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :assigned_to_id => 3)
989 assert_equal 3, copy.assigned_to_id
1008 assert_equal 3, copy.assigned_to_id
990 end
1009 end
991
1010
992 should "allow status changes" do
1011 should "allow status changes" do
993 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :status_id => 2)
1012 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :status_id => 2)
994 assert_equal 2, copy.status_id
1013 assert_equal 2, copy.status_id
995 end
1014 end
996
1015
997 should "allow start date changes" do
1016 should "allow start date changes" do
998 date = Date.today
1017 date = Date.today
999 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
1018 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
1000 assert_equal date, copy.start_date
1019 assert_equal date, copy.start_date
1001 end
1020 end
1002
1021
1003 should "allow due date changes" do
1022 should "allow due date changes" do
1004 date = Date.today
1023 date = Date.today
1005 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :due_date => date)
1024 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :due_date => date)
1006 assert_equal date, copy.due_date
1025 assert_equal date, copy.due_date
1007 end
1026 end
1008
1027
1009 should "set current user as author" do
1028 should "set current user as author" do
1010 User.current = User.find(9)
1029 User.current = User.find(9)
1011 copy = @issue.copy(:project_id => 3, :tracker_id => 2)
1030 copy = @issue.copy(:project_id => 3, :tracker_id => 2)
1012 assert_equal User.current, copy.author
1031 assert_equal User.current, copy.author
1013 end
1032 end
1014
1033
1015 should "create a journal with notes" do
1034 should "create a journal with notes" do
1016 date = Date.today
1035 date = Date.today
1017 notes = "Notes added when copying"
1036 notes = "Notes added when copying"
1018 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
1037 copy = @issue.copy(:project_id => 3, :tracker_id => 2, :start_date => date)
1019 copy.init_journal(User.current, notes)
1038 copy.init_journal(User.current, notes)
1020 copy.save!
1039 copy.save!
1021
1040
1022 assert_equal 1, copy.journals.size
1041 assert_equal 1, copy.journals.size
1023 journal = copy.journals.first
1042 journal = copy.journals.first
1024 assert_equal 0, journal.details.size
1043 assert_equal 0, journal.details.size
1025 assert_equal notes, journal.notes
1044 assert_equal notes, journal.notes
1026 end
1045 end
1027 end
1046 end
1028
1047
1029 def test_valid_parent_project
1048 def test_valid_parent_project
1030 issue = Issue.find(1)
1049 issue = Issue.find(1)
1031 issue_in_same_project = Issue.find(2)
1050 issue_in_same_project = Issue.find(2)
1032 issue_in_child_project = Issue.find(5)
1051 issue_in_child_project = Issue.find(5)
1033 issue_in_grandchild_project = Issue.generate!(:project_id => 6, :tracker_id => 1)
1052 issue_in_grandchild_project = Issue.generate!(:project_id => 6, :tracker_id => 1)
1034 issue_in_other_child_project = Issue.find(6)
1053 issue_in_other_child_project = Issue.find(6)
1035 issue_in_different_tree = Issue.find(4)
1054 issue_in_different_tree = Issue.find(4)
1036
1055
1037 with_settings :cross_project_subtasks => '' do
1056 with_settings :cross_project_subtasks => '' do
1038 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1057 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1039 assert_equal false, issue.valid_parent_project?(issue_in_child_project)
1058 assert_equal false, issue.valid_parent_project?(issue_in_child_project)
1040 assert_equal false, issue.valid_parent_project?(issue_in_grandchild_project)
1059 assert_equal false, issue.valid_parent_project?(issue_in_grandchild_project)
1041 assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
1060 assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
1042 end
1061 end
1043
1062
1044 with_settings :cross_project_subtasks => 'system' do
1063 with_settings :cross_project_subtasks => 'system' do
1045 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1064 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1046 assert_equal true, issue.valid_parent_project?(issue_in_child_project)
1065 assert_equal true, issue.valid_parent_project?(issue_in_child_project)
1047 assert_equal true, issue.valid_parent_project?(issue_in_different_tree)
1066 assert_equal true, issue.valid_parent_project?(issue_in_different_tree)
1048 end
1067 end
1049
1068
1050 with_settings :cross_project_subtasks => 'tree' do
1069 with_settings :cross_project_subtasks => 'tree' do
1051 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1070 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1052 assert_equal true, issue.valid_parent_project?(issue_in_child_project)
1071 assert_equal true, issue.valid_parent_project?(issue_in_child_project)
1053 assert_equal true, issue.valid_parent_project?(issue_in_grandchild_project)
1072 assert_equal true, issue.valid_parent_project?(issue_in_grandchild_project)
1054 assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
1073 assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
1055
1074
1056 assert_equal true, issue_in_child_project.valid_parent_project?(issue_in_same_project)
1075 assert_equal true, issue_in_child_project.valid_parent_project?(issue_in_same_project)
1057 assert_equal true, issue_in_child_project.valid_parent_project?(issue_in_other_child_project)
1076 assert_equal true, issue_in_child_project.valid_parent_project?(issue_in_other_child_project)
1058 end
1077 end
1059
1078
1060 with_settings :cross_project_subtasks => 'descendants' do
1079 with_settings :cross_project_subtasks => 'descendants' do
1061 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1080 assert_equal true, issue.valid_parent_project?(issue_in_same_project)
1062 assert_equal false, issue.valid_parent_project?(issue_in_child_project)
1081 assert_equal false, issue.valid_parent_project?(issue_in_child_project)
1063 assert_equal false, issue.valid_parent_project?(issue_in_grandchild_project)
1082 assert_equal false, issue.valid_parent_project?(issue_in_grandchild_project)
1064 assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
1083 assert_equal false, issue.valid_parent_project?(issue_in_different_tree)
1065
1084
1066 assert_equal true, issue_in_child_project.valid_parent_project?(issue)
1085 assert_equal true, issue_in_child_project.valid_parent_project?(issue)
1067 assert_equal false, issue_in_child_project.valid_parent_project?(issue_in_other_child_project)
1086 assert_equal false, issue_in_child_project.valid_parent_project?(issue_in_other_child_project)
1068 end
1087 end
1069 end
1088 end
1070
1089
1071 def test_recipients_should_include_previous_assignee
1090 def test_recipients_should_include_previous_assignee
1072 user = User.find(3)
1091 user = User.find(3)
1073 user.members.update_all ["mail_notification = ?", false]
1092 user.members.update_all ["mail_notification = ?", false]
1074 user.update_attribute :mail_notification, 'only_assigned'
1093 user.update_attribute :mail_notification, 'only_assigned'
1075
1094
1076 issue = Issue.find(2)
1095 issue = Issue.find(2)
1077 issue.assigned_to = nil
1096 issue.assigned_to = nil
1078 assert_include user.mail, issue.recipients
1097 assert_include user.mail, issue.recipients
1079 issue.save!
1098 issue.save!
1080 assert !issue.recipients.include?(user.mail)
1099 assert !issue.recipients.include?(user.mail)
1081 end
1100 end
1082
1101
1083 def test_recipients_should_not_include_users_that_cannot_view_the_issue
1102 def test_recipients_should_not_include_users_that_cannot_view_the_issue
1084 issue = Issue.find(12)
1103 issue = Issue.find(12)
1085 assert issue.recipients.include?(issue.author.mail)
1104 assert issue.recipients.include?(issue.author.mail)
1086 # copy the issue to a private project
1105 # copy the issue to a private project
1087 copy = issue.copy(:project_id => 5, :tracker_id => 2)
1106 copy = issue.copy(:project_id => 5, :tracker_id => 2)
1088 # author is not a member of project anymore
1107 # author is not a member of project anymore
1089 assert !copy.recipients.include?(copy.author.mail)
1108 assert !copy.recipients.include?(copy.author.mail)
1090 end
1109 end
1091
1110
1092 def test_recipients_should_include_the_assigned_group_members
1111 def test_recipients_should_include_the_assigned_group_members
1093 group_member = User.generate!
1112 group_member = User.generate!
1094 group = Group.generate!
1113 group = Group.generate!
1095 group.users << group_member
1114 group.users << group_member
1096
1115
1097 issue = Issue.find(12)
1116 issue = Issue.find(12)
1098 issue.assigned_to = group
1117 issue.assigned_to = group
1099 assert issue.recipients.include?(group_member.mail)
1118 assert issue.recipients.include?(group_member.mail)
1100 end
1119 end
1101
1120
1102 def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
1121 def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
1103 user = User.find(3)
1122 user = User.find(3)
1104 issue = Issue.find(9)
1123 issue = Issue.find(9)
1105 Watcher.create!(:user => user, :watchable => issue)
1124 Watcher.create!(:user => user, :watchable => issue)
1106 assert issue.watched_by?(user)
1125 assert issue.watched_by?(user)
1107 assert !issue.watcher_recipients.include?(user.mail)
1126 assert !issue.watcher_recipients.include?(user.mail)
1108 end
1127 end
1109
1128
1110 def test_issue_destroy
1129 def test_issue_destroy
1111 Issue.find(1).destroy
1130 Issue.find(1).destroy
1112 assert_nil Issue.find_by_id(1)
1131 assert_nil Issue.find_by_id(1)
1113 assert_nil TimeEntry.find_by_issue_id(1)
1132 assert_nil TimeEntry.find_by_issue_id(1)
1114 end
1133 end
1115
1134
1116 def test_destroying_a_deleted_issue_should_not_raise_an_error
1135 def test_destroying_a_deleted_issue_should_not_raise_an_error
1117 issue = Issue.find(1)
1136 issue = Issue.find(1)
1118 Issue.find(1).destroy
1137 Issue.find(1).destroy
1119
1138
1120 assert_nothing_raised do
1139 assert_nothing_raised do
1121 assert_no_difference 'Issue.count' do
1140 assert_no_difference 'Issue.count' do
1122 issue.destroy
1141 issue.destroy
1123 end
1142 end
1124 assert issue.destroyed?
1143 assert issue.destroyed?
1125 end
1144 end
1126 end
1145 end
1127
1146
1128 def test_destroying_a_stale_issue_should_not_raise_an_error
1147 def test_destroying_a_stale_issue_should_not_raise_an_error
1129 issue = Issue.find(1)
1148 issue = Issue.find(1)
1130 Issue.find(1).update_attribute :subject, "Updated"
1149 Issue.find(1).update_attribute :subject, "Updated"
1131
1150
1132 assert_nothing_raised do
1151 assert_nothing_raised do
1133 assert_difference 'Issue.count', -1 do
1152 assert_difference 'Issue.count', -1 do
1134 issue.destroy
1153 issue.destroy
1135 end
1154 end
1136 assert issue.destroyed?
1155 assert issue.destroyed?
1137 end
1156 end
1138 end
1157 end
1139
1158
1140 def test_blocked
1159 def test_blocked
1141 blocked_issue = Issue.find(9)
1160 blocked_issue = Issue.find(9)
1142 blocking_issue = Issue.find(10)
1161 blocking_issue = Issue.find(10)
1143
1162
1144 assert blocked_issue.blocked?
1163 assert blocked_issue.blocked?
1145 assert !blocking_issue.blocked?
1164 assert !blocking_issue.blocked?
1146 end
1165 end
1147
1166
1148 def test_blocked_issues_dont_allow_closed_statuses
1167 def test_blocked_issues_dont_allow_closed_statuses
1149 blocked_issue = Issue.find(9)
1168 blocked_issue = Issue.find(9)
1150
1169
1151 allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
1170 allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
1152 assert !allowed_statuses.empty?
1171 assert !allowed_statuses.empty?
1153 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
1172 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
1154 assert closed_statuses.empty?
1173 assert closed_statuses.empty?
1155 end
1174 end
1156
1175
1157 def test_unblocked_issues_allow_closed_statuses
1176 def test_unblocked_issues_allow_closed_statuses
1158 blocking_issue = Issue.find(10)
1177 blocking_issue = Issue.find(10)
1159
1178
1160 allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
1179 allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
1161 assert !allowed_statuses.empty?
1180 assert !allowed_statuses.empty?
1162 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
1181 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
1163 assert !closed_statuses.empty?
1182 assert !closed_statuses.empty?
1164 end
1183 end
1165
1184
1166 def test_rescheduling_an_issue_should_reschedule_following_issue
1185 def test_rescheduling_an_issue_should_reschedule_following_issue
1167 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)
1186 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)
1168 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)
1187 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)
1169 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
1188 IssueRelation.create!(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_PRECEDES)
1170 assert_equal issue1.due_date + 1, issue2.reload.start_date
1189 assert_equal issue1.due_date + 1, issue2.reload.start_date
1171
1190
1172 issue1.due_date = Date.today + 5
1191 issue1.due_date = Date.today + 5
1173 issue1.save!
1192 issue1.save!
1174 assert_equal issue1.due_date + 1, issue2.reload.start_date
1193 assert_equal issue1.due_date + 1, issue2.reload.start_date
1175 end
1194 end
1176
1195
1177 def test_rescheduling_a_stale_issue_should_not_raise_an_error
1196 def test_rescheduling_a_stale_issue_should_not_raise_an_error
1178 stale = Issue.find(1)
1197 stale = Issue.find(1)
1179 issue = Issue.find(1)
1198 issue = Issue.find(1)
1180 issue.subject = "Updated"
1199 issue.subject = "Updated"
1181 issue.save!
1200 issue.save!
1182
1201
1183 date = 10.days.from_now.to_date
1202 date = 10.days.from_now.to_date
1184 assert_nothing_raised do
1203 assert_nothing_raised do
1185 stale.reschedule_after(date)
1204 stale.reschedule_after(date)
1186 end
1205 end
1187 assert_equal date, stale.reload.start_date
1206 assert_equal date, stale.reload.start_date
1188 end
1207 end
1189
1208
1190 def test_overdue
1209 def test_overdue
1191 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
1210 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
1192 assert !Issue.new(:due_date => Date.today).overdue?
1211 assert !Issue.new(:due_date => Date.today).overdue?
1193 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
1212 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
1194 assert !Issue.new(:due_date => nil).overdue?
1213 assert !Issue.new(:due_date => nil).overdue?
1195 assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
1214 assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
1196 end
1215 end
1197
1216
1198 context "#behind_schedule?" do
1217 context "#behind_schedule?" do
1199 should "be false if the issue has no start_date" do
1218 should "be false if the issue has no start_date" do
1200 assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
1219 assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
1201 end
1220 end
1202
1221
1203 should "be false if the issue has no end_date" do
1222 should "be false if the issue has no end_date" do
1204 assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
1223 assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
1205 end
1224 end
1206
1225
1207 should "be false if the issue has more done than it's calendar time" do
1226 should "be false if the issue has more done than it's calendar time" do
1208 assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
1227 assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
1209 end
1228 end
1210
1229
1211 should "be true if the issue hasn't been started at all" do
1230 should "be true if the issue hasn't been started at all" do
1212 assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
1231 assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
1213 end
1232 end
1214
1233
1215 should "be true if the issue has used more calendar time than it's done ratio" do
1234 should "be true if the issue has used more calendar time than it's done ratio" do
1216 assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
1235 assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
1217 end
1236 end
1218 end
1237 end
1219
1238
1220 context "#assignable_users" do
1239 context "#assignable_users" do
1221 should "be Users" do
1240 should "be Users" do
1222 assert_kind_of User, Issue.find(1).assignable_users.first
1241 assert_kind_of User, Issue.find(1).assignable_users.first
1223 end
1242 end
1224
1243
1225 should "include the issue author" do
1244 should "include the issue author" do
1226 non_project_member = User.generate!
1245 non_project_member = User.generate!
1227 issue = Issue.generate!(:author => non_project_member)
1246 issue = Issue.generate!(:author => non_project_member)
1228
1247
1229 assert issue.assignable_users.include?(non_project_member)
1248 assert issue.assignable_users.include?(non_project_member)
1230 end
1249 end
1231
1250
1232 should "include the current assignee" do
1251 should "include the current assignee" do
1233 user = User.generate!
1252 user = User.generate!
1234 issue = Issue.generate!(:assigned_to => user)
1253 issue = Issue.generate!(:assigned_to => user)
1235 user.lock!
1254 user.lock!
1236
1255
1237 assert Issue.find(issue.id).assignable_users.include?(user)
1256 assert Issue.find(issue.id).assignable_users.include?(user)
1238 end
1257 end
1239
1258
1240 should "not show the issue author twice" do
1259 should "not show the issue author twice" do
1241 assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
1260 assignable_user_ids = Issue.find(1).assignable_users.collect(&:id)
1242 assert_equal 2, assignable_user_ids.length
1261 assert_equal 2, assignable_user_ids.length
1243
1262
1244 assignable_user_ids.each do |user_id|
1263 assignable_user_ids.each do |user_id|
1245 assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, "User #{user_id} appears more or less than once"
1264 assert_equal 1, assignable_user_ids.select {|i| i == user_id}.length, "User #{user_id} appears more or less than once"
1246 end
1265 end
1247 end
1266 end
1248
1267
1249 context "with issue_group_assignment" do
1268 context "with issue_group_assignment" do
1250 should "include groups" do
1269 should "include groups" do
1251 issue = Issue.new(:project => Project.find(2))
1270 issue = Issue.new(:project => Project.find(2))
1252
1271
1253 with_settings :issue_group_assignment => '1' do
1272 with_settings :issue_group_assignment => '1' do
1254 assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
1273 assert_equal %w(Group User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
1255 assert issue.assignable_users.include?(Group.find(11))
1274 assert issue.assignable_users.include?(Group.find(11))
1256 end
1275 end
1257 end
1276 end
1258 end
1277 end
1259
1278
1260 context "without issue_group_assignment" do
1279 context "without issue_group_assignment" do
1261 should "not include groups" do
1280 should "not include groups" do
1262 issue = Issue.new(:project => Project.find(2))
1281 issue = Issue.new(:project => Project.find(2))
1263
1282
1264 with_settings :issue_group_assignment => '0' do
1283 with_settings :issue_group_assignment => '0' do
1265 assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
1284 assert_equal %w(User), issue.assignable_users.map {|a| a.class.name}.uniq.sort
1266 assert !issue.assignable_users.include?(Group.find(11))
1285 assert !issue.assignable_users.include?(Group.find(11))
1267 end
1286 end
1268 end
1287 end
1269 end
1288 end
1270 end
1289 end
1271
1290
1272 def test_create_should_send_email_notification
1291 def test_create_should_send_email_notification
1273 ActionMailer::Base.deliveries.clear
1292 ActionMailer::Base.deliveries.clear
1274 issue = Issue.new(:project_id => 1, :tracker_id => 1,
1293 issue = Issue.new(:project_id => 1, :tracker_id => 1,
1275 :author_id => 3, :status_id => 1,
1294 :author_id => 3, :status_id => 1,
1276 :priority => IssuePriority.all.first,
1295 :priority => IssuePriority.all.first,
1277 :subject => 'test_create', :estimated_hours => '1:30')
1296 :subject => 'test_create', :estimated_hours => '1:30')
1278
1297
1279 assert issue.save
1298 assert issue.save
1280 assert_equal 1, ActionMailer::Base.deliveries.size
1299 assert_equal 1, ActionMailer::Base.deliveries.size
1281 end
1300 end
1282
1301
1283 def test_stale_issue_should_not_send_email_notification
1302 def test_stale_issue_should_not_send_email_notification
1284 ActionMailer::Base.deliveries.clear
1303 ActionMailer::Base.deliveries.clear
1285 issue = Issue.find(1)
1304 issue = Issue.find(1)
1286 stale = Issue.find(1)
1305 stale = Issue.find(1)
1287
1306
1288 issue.init_journal(User.find(1))
1307 issue.init_journal(User.find(1))
1289 issue.subject = 'Subjet update'
1308 issue.subject = 'Subjet update'
1290 assert issue.save
1309 assert issue.save
1291 assert_equal 1, ActionMailer::Base.deliveries.size
1310 assert_equal 1, ActionMailer::Base.deliveries.size
1292 ActionMailer::Base.deliveries.clear
1311 ActionMailer::Base.deliveries.clear
1293
1312
1294 stale.init_journal(User.find(1))
1313 stale.init_journal(User.find(1))
1295 stale.subject = 'Another subjet update'
1314 stale.subject = 'Another subjet update'
1296 assert_raise ActiveRecord::StaleObjectError do
1315 assert_raise ActiveRecord::StaleObjectError do
1297 stale.save
1316 stale.save
1298 end
1317 end
1299 assert ActionMailer::Base.deliveries.empty?
1318 assert ActionMailer::Base.deliveries.empty?
1300 end
1319 end
1301
1320
1302 def test_journalized_description
1321 def test_journalized_description
1303 IssueCustomField.delete_all
1322 IssueCustomField.delete_all
1304
1323
1305 i = Issue.first
1324 i = Issue.first
1306 old_description = i.description
1325 old_description = i.description
1307 new_description = "This is the new description"
1326 new_description = "This is the new description"
1308
1327
1309 i.init_journal(User.find(2))
1328 i.init_journal(User.find(2))
1310 i.description = new_description
1329 i.description = new_description
1311 assert_difference 'Journal.count', 1 do
1330 assert_difference 'Journal.count', 1 do
1312 assert_difference 'JournalDetail.count', 1 do
1331 assert_difference 'JournalDetail.count', 1 do
1313 i.save!
1332 i.save!
1314 end
1333 end
1315 end
1334 end
1316
1335
1317 detail = JournalDetail.first(:order => 'id DESC')
1336 detail = JournalDetail.first(:order => 'id DESC')
1318 assert_equal i, detail.journal.journalized
1337 assert_equal i, detail.journal.journalized
1319 assert_equal 'attr', detail.property
1338 assert_equal 'attr', detail.property
1320 assert_equal 'description', detail.prop_key
1339 assert_equal 'description', detail.prop_key
1321 assert_equal old_description, detail.old_value
1340 assert_equal old_description, detail.old_value
1322 assert_equal new_description, detail.value
1341 assert_equal new_description, detail.value
1323 end
1342 end
1324
1343
1325 def test_blank_descriptions_should_not_be_journalized
1344 def test_blank_descriptions_should_not_be_journalized
1326 IssueCustomField.delete_all
1345 IssueCustomField.delete_all
1327 Issue.update_all("description = NULL", "id=1")
1346 Issue.update_all("description = NULL", "id=1")
1328
1347
1329 i = Issue.find(1)
1348 i = Issue.find(1)
1330 i.init_journal(User.find(2))
1349 i.init_journal(User.find(2))
1331 i.subject = "blank description"
1350 i.subject = "blank description"
1332 i.description = "\r\n"
1351 i.description = "\r\n"
1333
1352
1334 assert_difference 'Journal.count', 1 do
1353 assert_difference 'Journal.count', 1 do
1335 assert_difference 'JournalDetail.count', 1 do
1354 assert_difference 'JournalDetail.count', 1 do
1336 i.save!
1355 i.save!
1337 end
1356 end
1338 end
1357 end
1339 end
1358 end
1340
1359
1341 def test_journalized_multi_custom_field
1360 def test_journalized_multi_custom_field
1342 field = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
1361 field = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
1343 :tracker_ids => [1], :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
1362 :tracker_ids => [1], :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
1344
1363
1345 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'Test', :author_id => 1)
1364 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'Test', :author_id => 1)
1346
1365
1347 assert_difference 'Journal.count' do
1366 assert_difference 'Journal.count' do
1348 assert_difference 'JournalDetail.count' do
1367 assert_difference 'JournalDetail.count' do
1349 issue.init_journal(User.first)
1368 issue.init_journal(User.first)
1350 issue.custom_field_values = {field.id => ['value1']}
1369 issue.custom_field_values = {field.id => ['value1']}
1351 issue.save!
1370 issue.save!
1352 end
1371 end
1353 assert_difference 'JournalDetail.count' do
1372 assert_difference 'JournalDetail.count' do
1354 issue.init_journal(User.first)
1373 issue.init_journal(User.first)
1355 issue.custom_field_values = {field.id => ['value1', 'value2']}
1374 issue.custom_field_values = {field.id => ['value1', 'value2']}
1356 issue.save!
1375 issue.save!
1357 end
1376 end
1358 assert_difference 'JournalDetail.count', 2 do
1377 assert_difference 'JournalDetail.count', 2 do
1359 issue.init_journal(User.first)
1378 issue.init_journal(User.first)
1360 issue.custom_field_values = {field.id => ['value3', 'value2']}
1379 issue.custom_field_values = {field.id => ['value3', 'value2']}
1361 issue.save!
1380 issue.save!
1362 end
1381 end
1363 assert_difference 'JournalDetail.count', 2 do
1382 assert_difference 'JournalDetail.count', 2 do
1364 issue.init_journal(User.first)
1383 issue.init_journal(User.first)
1365 issue.custom_field_values = {field.id => nil}
1384 issue.custom_field_values = {field.id => nil}
1366 issue.save!
1385 issue.save!
1367 end
1386 end
1368 end
1387 end
1369 end
1388 end
1370
1389
1371 def test_description_eol_should_be_normalized
1390 def test_description_eol_should_be_normalized
1372 i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
1391 i = Issue.new(:description => "CR \r LF \n CRLF \r\n")
1373 assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
1392 assert_equal "CR \r\n LF \r\n CRLF \r\n", i.description
1374 end
1393 end
1375
1394
1376 def test_saving_twice_should_not_duplicate_journal_details
1395 def test_saving_twice_should_not_duplicate_journal_details
1377 i = Issue.find(:first)
1396 i = Issue.find(:first)
1378 i.init_journal(User.find(2), 'Some notes')
1397 i.init_journal(User.find(2), 'Some notes')
1379 # initial changes
1398 # initial changes
1380 i.subject = 'New subject'
1399 i.subject = 'New subject'
1381 i.done_ratio = i.done_ratio + 10
1400 i.done_ratio = i.done_ratio + 10
1382 assert_difference 'Journal.count' do
1401 assert_difference 'Journal.count' do
1383 assert i.save
1402 assert i.save
1384 end
1403 end
1385 # 1 more change
1404 # 1 more change
1386 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
1405 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
1387 assert_no_difference 'Journal.count' do
1406 assert_no_difference 'Journal.count' do
1388 assert_difference 'JournalDetail.count', 1 do
1407 assert_difference 'JournalDetail.count', 1 do
1389 i.save
1408 i.save
1390 end
1409 end
1391 end
1410 end
1392 # no more change
1411 # no more change
1393 assert_no_difference 'Journal.count' do
1412 assert_no_difference 'Journal.count' do
1394 assert_no_difference 'JournalDetail.count' do
1413 assert_no_difference 'JournalDetail.count' do
1395 i.save
1414 i.save
1396 end
1415 end
1397 end
1416 end
1398 end
1417 end
1399
1418
1400 def test_all_dependent_issues
1419 def test_all_dependent_issues
1401 IssueRelation.delete_all
1420 IssueRelation.delete_all
1402 assert IssueRelation.create!(:issue_from => Issue.find(1),
1421 assert IssueRelation.create!(:issue_from => Issue.find(1),
1403 :issue_to => Issue.find(2),
1422 :issue_to => Issue.find(2),
1404 :relation_type => IssueRelation::TYPE_PRECEDES)
1423 :relation_type => IssueRelation::TYPE_PRECEDES)
1405 assert IssueRelation.create!(:issue_from => Issue.find(2),
1424 assert IssueRelation.create!(:issue_from => Issue.find(2),
1406 :issue_to => Issue.find(3),
1425 :issue_to => Issue.find(3),
1407 :relation_type => IssueRelation::TYPE_PRECEDES)
1426 :relation_type => IssueRelation::TYPE_PRECEDES)
1408 assert IssueRelation.create!(:issue_from => Issue.find(3),
1427 assert IssueRelation.create!(:issue_from => Issue.find(3),
1409 :issue_to => Issue.find(8),
1428 :issue_to => Issue.find(8),
1410 :relation_type => IssueRelation::TYPE_PRECEDES)
1429 :relation_type => IssueRelation::TYPE_PRECEDES)
1411
1430
1412 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
1431 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
1413 end
1432 end
1414
1433
1415 def test_all_dependent_issues_with_persistent_circular_dependency
1434 def test_all_dependent_issues_with_persistent_circular_dependency
1416 IssueRelation.delete_all
1435 IssueRelation.delete_all
1417 assert IssueRelation.create!(:issue_from => Issue.find(1),
1436 assert IssueRelation.create!(:issue_from => Issue.find(1),
1418 :issue_to => Issue.find(2),
1437 :issue_to => Issue.find(2),
1419 :relation_type => IssueRelation::TYPE_PRECEDES)
1438 :relation_type => IssueRelation::TYPE_PRECEDES)
1420 assert IssueRelation.create!(:issue_from => Issue.find(2),
1439 assert IssueRelation.create!(:issue_from => Issue.find(2),
1421 :issue_to => Issue.find(3),
1440 :issue_to => Issue.find(3),
1422 :relation_type => IssueRelation::TYPE_PRECEDES)
1441 :relation_type => IssueRelation::TYPE_PRECEDES)
1423
1442
1424 r = IssueRelation.create!(:issue_from => Issue.find(3),
1443 r = IssueRelation.create!(:issue_from => Issue.find(3),
1425 :issue_to => Issue.find(7),
1444 :issue_to => Issue.find(7),
1426 :relation_type => IssueRelation::TYPE_PRECEDES)
1445 :relation_type => IssueRelation::TYPE_PRECEDES)
1427 IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id])
1446 IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id])
1428
1447
1429 assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
1448 assert_equal [2, 3], Issue.find(1).all_dependent_issues.collect(&:id).sort
1430 end
1449 end
1431
1450
1432 def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
1451 def test_all_dependent_issues_with_persistent_multiple_circular_dependencies
1433 IssueRelation.delete_all
1452 IssueRelation.delete_all
1434 assert IssueRelation.create!(:issue_from => Issue.find(1),
1453 assert IssueRelation.create!(:issue_from => Issue.find(1),
1435 :issue_to => Issue.find(2),
1454 :issue_to => Issue.find(2),
1436 :relation_type => IssueRelation::TYPE_RELATES)
1455 :relation_type => IssueRelation::TYPE_RELATES)
1437 assert IssueRelation.create!(:issue_from => Issue.find(2),
1456 assert IssueRelation.create!(:issue_from => Issue.find(2),
1438 :issue_to => Issue.find(3),
1457 :issue_to => Issue.find(3),
1439 :relation_type => IssueRelation::TYPE_RELATES)
1458 :relation_type => IssueRelation::TYPE_RELATES)
1440 assert IssueRelation.create!(:issue_from => Issue.find(3),
1459 assert IssueRelation.create!(:issue_from => Issue.find(3),
1441 :issue_to => Issue.find(8),
1460 :issue_to => Issue.find(8),
1442 :relation_type => IssueRelation::TYPE_RELATES)
1461 :relation_type => IssueRelation::TYPE_RELATES)
1443
1462
1444 r = IssueRelation.create!(:issue_from => Issue.find(8),
1463 r = IssueRelation.create!(:issue_from => Issue.find(8),
1445 :issue_to => Issue.find(7),
1464 :issue_to => Issue.find(7),
1446 :relation_type => IssueRelation::TYPE_RELATES)
1465 :relation_type => IssueRelation::TYPE_RELATES)
1447 IssueRelation.update_all("issue_to_id = 2", ["id = ?", r.id])
1466 IssueRelation.update_all("issue_to_id = 2", ["id = ?", r.id])
1448
1467
1449 r = IssueRelation.create!(:issue_from => Issue.find(3),
1468 r = IssueRelation.create!(:issue_from => Issue.find(3),
1450 :issue_to => Issue.find(7),
1469 :issue_to => Issue.find(7),
1451 :relation_type => IssueRelation::TYPE_RELATES)
1470 :relation_type => IssueRelation::TYPE_RELATES)
1452 IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id])
1471 IssueRelation.update_all("issue_to_id = 1", ["id = ?", r.id])
1453
1472
1454 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
1473 assert_equal [2, 3, 8], Issue.find(1).all_dependent_issues.collect(&:id).sort
1455 end
1474 end
1456
1475
1457 context "#done_ratio" do
1476 context "#done_ratio" do
1458 setup do
1477 setup do
1459 @issue = Issue.find(1)
1478 @issue = Issue.find(1)
1460 @issue_status = IssueStatus.find(1)
1479 @issue_status = IssueStatus.find(1)
1461 @issue_status.update_attribute(:default_done_ratio, 50)
1480 @issue_status.update_attribute(:default_done_ratio, 50)
1462 @issue2 = Issue.find(2)
1481 @issue2 = Issue.find(2)
1463 @issue_status2 = IssueStatus.find(2)
1482 @issue_status2 = IssueStatus.find(2)
1464 @issue_status2.update_attribute(:default_done_ratio, 0)
1483 @issue_status2.update_attribute(:default_done_ratio, 0)
1465 end
1484 end
1466
1485
1467 teardown do
1486 teardown do
1468 Setting.issue_done_ratio = 'issue_field'
1487 Setting.issue_done_ratio = 'issue_field'
1469 end
1488 end
1470
1489
1471 context "with Setting.issue_done_ratio using the issue_field" do
1490 context "with Setting.issue_done_ratio using the issue_field" do
1472 setup do
1491 setup do
1473 Setting.issue_done_ratio = 'issue_field'
1492 Setting.issue_done_ratio = 'issue_field'
1474 end
1493 end
1475
1494
1476 should "read the issue's field" do
1495 should "read the issue's field" do
1477 assert_equal 0, @issue.done_ratio
1496 assert_equal 0, @issue.done_ratio
1478 assert_equal 30, @issue2.done_ratio
1497 assert_equal 30, @issue2.done_ratio
1479 end
1498 end
1480 end
1499 end
1481
1500
1482 context "with Setting.issue_done_ratio using the issue_status" do
1501 context "with Setting.issue_done_ratio using the issue_status" do
1483 setup do
1502 setup do
1484 Setting.issue_done_ratio = 'issue_status'
1503 Setting.issue_done_ratio = 'issue_status'
1485 end
1504 end
1486
1505
1487 should "read the Issue Status's default done ratio" do
1506 should "read the Issue Status's default done ratio" do
1488 assert_equal 50, @issue.done_ratio
1507 assert_equal 50, @issue.done_ratio
1489 assert_equal 0, @issue2.done_ratio
1508 assert_equal 0, @issue2.done_ratio
1490 end
1509 end
1491 end
1510 end
1492 end
1511 end
1493
1512
1494 context "#update_done_ratio_from_issue_status" do
1513 context "#update_done_ratio_from_issue_status" do
1495 setup do
1514 setup do
1496 @issue = Issue.find(1)
1515 @issue = Issue.find(1)
1497 @issue_status = IssueStatus.find(1)
1516 @issue_status = IssueStatus.find(1)
1498 @issue_status.update_attribute(:default_done_ratio, 50)
1517 @issue_status.update_attribute(:default_done_ratio, 50)
1499 @issue2 = Issue.find(2)
1518 @issue2 = Issue.find(2)
1500 @issue_status2 = IssueStatus.find(2)
1519 @issue_status2 = IssueStatus.find(2)
1501 @issue_status2.update_attribute(:default_done_ratio, 0)
1520 @issue_status2.update_attribute(:default_done_ratio, 0)
1502 end
1521 end
1503
1522
1504 context "with Setting.issue_done_ratio using the issue_field" do
1523 context "with Setting.issue_done_ratio using the issue_field" do
1505 setup do
1524 setup do
1506 Setting.issue_done_ratio = 'issue_field'
1525 Setting.issue_done_ratio = 'issue_field'
1507 end
1526 end
1508
1527
1509 should "not change the issue" do
1528 should "not change the issue" do
1510 @issue.update_done_ratio_from_issue_status
1529 @issue.update_done_ratio_from_issue_status
1511 @issue2.update_done_ratio_from_issue_status
1530 @issue2.update_done_ratio_from_issue_status
1512
1531
1513 assert_equal 0, @issue.read_attribute(:done_ratio)
1532 assert_equal 0, @issue.read_attribute(:done_ratio)
1514 assert_equal 30, @issue2.read_attribute(:done_ratio)
1533 assert_equal 30, @issue2.read_attribute(:done_ratio)
1515 end
1534 end
1516 end
1535 end
1517
1536
1518 context "with Setting.issue_done_ratio using the issue_status" do
1537 context "with Setting.issue_done_ratio using the issue_status" do
1519 setup do
1538 setup do
1520 Setting.issue_done_ratio = 'issue_status'
1539 Setting.issue_done_ratio = 'issue_status'
1521 end
1540 end
1522
1541
1523 should "change the issue's done ratio" do
1542 should "change the issue's done ratio" do
1524 @issue.update_done_ratio_from_issue_status
1543 @issue.update_done_ratio_from_issue_status
1525 @issue2.update_done_ratio_from_issue_status
1544 @issue2.update_done_ratio_from_issue_status
1526
1545
1527 assert_equal 50, @issue.read_attribute(:done_ratio)
1546 assert_equal 50, @issue.read_attribute(:done_ratio)
1528 assert_equal 0, @issue2.read_attribute(:done_ratio)
1547 assert_equal 0, @issue2.read_attribute(:done_ratio)
1529 end
1548 end
1530 end
1549 end
1531 end
1550 end
1532
1551
1533 test "#by_tracker" do
1552 test "#by_tracker" do
1534 User.current = User.anonymous
1553 User.current = User.anonymous
1535 groups = Issue.by_tracker(Project.find(1))
1554 groups = Issue.by_tracker(Project.find(1))
1536 assert_equal 3, groups.size
1555 assert_equal 3, groups.size
1537 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1556 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1538 end
1557 end
1539
1558
1540 test "#by_version" do
1559 test "#by_version" do
1541 User.current = User.anonymous
1560 User.current = User.anonymous
1542 groups = Issue.by_version(Project.find(1))
1561 groups = Issue.by_version(Project.find(1))
1543 assert_equal 3, groups.size
1562 assert_equal 3, groups.size
1544 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1563 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1545 end
1564 end
1546
1565
1547 test "#by_priority" do
1566 test "#by_priority" do
1548 User.current = User.anonymous
1567 User.current = User.anonymous
1549 groups = Issue.by_priority(Project.find(1))
1568 groups = Issue.by_priority(Project.find(1))
1550 assert_equal 4, groups.size
1569 assert_equal 4, groups.size
1551 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1570 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1552 end
1571 end
1553
1572
1554 test "#by_category" do
1573 test "#by_category" do
1555 User.current = User.anonymous
1574 User.current = User.anonymous
1556 groups = Issue.by_category(Project.find(1))
1575 groups = Issue.by_category(Project.find(1))
1557 assert_equal 2, groups.size
1576 assert_equal 2, groups.size
1558 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1577 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1559 end
1578 end
1560
1579
1561 test "#by_assigned_to" do
1580 test "#by_assigned_to" do
1562 User.current = User.anonymous
1581 User.current = User.anonymous
1563 groups = Issue.by_assigned_to(Project.find(1))
1582 groups = Issue.by_assigned_to(Project.find(1))
1564 assert_equal 2, groups.size
1583 assert_equal 2, groups.size
1565 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1584 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1566 end
1585 end
1567
1586
1568 test "#by_author" do
1587 test "#by_author" do
1569 User.current = User.anonymous
1588 User.current = User.anonymous
1570 groups = Issue.by_author(Project.find(1))
1589 groups = Issue.by_author(Project.find(1))
1571 assert_equal 4, groups.size
1590 assert_equal 4, groups.size
1572 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1591 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1573 end
1592 end
1574
1593
1575 test "#by_subproject" do
1594 test "#by_subproject" do
1576 User.current = User.anonymous
1595 User.current = User.anonymous
1577 groups = Issue.by_subproject(Project.find(1))
1596 groups = Issue.by_subproject(Project.find(1))
1578 # Private descendant not visible
1597 # Private descendant not visible
1579 assert_equal 1, groups.size
1598 assert_equal 1, groups.size
1580 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1599 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
1581 end
1600 end
1582
1601
1583 def test_recently_updated_scope
1602 def test_recently_updated_scope
1584 #should return the last updated issue
1603 #should return the last updated issue
1585 assert_equal Issue.reorder("updated_on DESC").first, Issue.recently_updated.limit(1).first
1604 assert_equal Issue.reorder("updated_on DESC").first, Issue.recently_updated.limit(1).first
1586 end
1605 end
1587
1606
1588 def test_on_active_projects_scope
1607 def test_on_active_projects_scope
1589 assert Project.find(2).archive
1608 assert Project.find(2).archive
1590
1609
1591 before = Issue.on_active_project.length
1610 before = Issue.on_active_project.length
1592 # test inclusion to results
1611 # test inclusion to results
1593 issue = Issue.generate!(:tracker => Project.find(2).trackers.first)
1612 issue = Issue.generate!(:tracker => Project.find(2).trackers.first)
1594 assert_equal before + 1, Issue.on_active_project.length
1613 assert_equal before + 1, Issue.on_active_project.length
1595
1614
1596 # Move to an archived project
1615 # Move to an archived project
1597 issue.project = Project.find(2)
1616 issue.project = Project.find(2)
1598 assert issue.save
1617 assert issue.save
1599 assert_equal before, Issue.on_active_project.length
1618 assert_equal before, Issue.on_active_project.length
1600 end
1619 end
1601
1620
1602 context "Issue#recipients" do
1621 context "Issue#recipients" do
1603 setup do
1622 setup do
1604 @project = Project.find(1)
1623 @project = Project.find(1)
1605 @author = User.generate!
1624 @author = User.generate!
1606 @assignee = User.generate!
1625 @assignee = User.generate!
1607 @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author)
1626 @issue = Issue.generate!(:project => @project, :assigned_to => @assignee, :author => @author)
1608 end
1627 end
1609
1628
1610 should "include project recipients" do
1629 should "include project recipients" do
1611 assert @project.recipients.present?
1630 assert @project.recipients.present?
1612 @project.recipients.each do |project_recipient|
1631 @project.recipients.each do |project_recipient|
1613 assert @issue.recipients.include?(project_recipient)
1632 assert @issue.recipients.include?(project_recipient)
1614 end
1633 end
1615 end
1634 end
1616
1635
1617 should "include the author if the author is active" do
1636 should "include the author if the author is active" do
1618 assert @issue.author, "No author set for Issue"
1637 assert @issue.author, "No author set for Issue"
1619 assert @issue.recipients.include?(@issue.author.mail)
1638 assert @issue.recipients.include?(@issue.author.mail)
1620 end
1639 end
1621
1640
1622 should "include the assigned to user if the assigned to user is active" do
1641 should "include the assigned to user if the assigned to user is active" do
1623 assert @issue.assigned_to, "No assigned_to set for Issue"
1642 assert @issue.assigned_to, "No assigned_to set for Issue"
1624 assert @issue.recipients.include?(@issue.assigned_to.mail)
1643 assert @issue.recipients.include?(@issue.assigned_to.mail)
1625 end
1644 end
1626
1645
1627 should "not include users who opt out of all email" do
1646 should "not include users who opt out of all email" do
1628 @author.update_attribute(:mail_notification, :none)
1647 @author.update_attribute(:mail_notification, :none)
1629
1648
1630 assert !@issue.recipients.include?(@issue.author.mail)
1649 assert !@issue.recipients.include?(@issue.author.mail)
1631 end
1650 end
1632
1651
1633 should "not include the issue author if they are only notified of assigned issues" do
1652 should "not include the issue author if they are only notified of assigned issues" do
1634 @author.update_attribute(:mail_notification, :only_assigned)
1653 @author.update_attribute(:mail_notification, :only_assigned)
1635
1654
1636 assert !@issue.recipients.include?(@issue.author.mail)
1655 assert !@issue.recipients.include?(@issue.author.mail)
1637 end
1656 end
1638
1657
1639 should "not include the assigned user if they are only notified of owned issues" do
1658 should "not include the assigned user if they are only notified of owned issues" do
1640 @assignee.update_attribute(:mail_notification, :only_owner)
1659 @assignee.update_attribute(:mail_notification, :only_owner)
1641
1660
1642 assert !@issue.recipients.include?(@issue.assigned_to.mail)
1661 assert !@issue.recipients.include?(@issue.assigned_to.mail)
1643 end
1662 end
1644 end
1663 end
1645
1664
1646 def test_last_journal_id_with_journals_should_return_the_journal_id
1665 def test_last_journal_id_with_journals_should_return_the_journal_id
1647 assert_equal 2, Issue.find(1).last_journal_id
1666 assert_equal 2, Issue.find(1).last_journal_id
1648 end
1667 end
1649
1668
1650 def test_last_journal_id_without_journals_should_return_nil
1669 def test_last_journal_id_without_journals_should_return_nil
1651 assert_nil Issue.find(3).last_journal_id
1670 assert_nil Issue.find(3).last_journal_id
1652 end
1671 end
1653
1672
1654 def test_journals_after_should_return_journals_with_greater_id
1673 def test_journals_after_should_return_journals_with_greater_id
1655 assert_equal [Journal.find(2)], Issue.find(1).journals_after('1')
1674 assert_equal [Journal.find(2)], Issue.find(1).journals_after('1')
1656 assert_equal [], Issue.find(1).journals_after('2')
1675 assert_equal [], Issue.find(1).journals_after('2')
1657 end
1676 end
1658
1677
1659 def test_journals_after_with_blank_arg_should_return_all_journals
1678 def test_journals_after_with_blank_arg_should_return_all_journals
1660 assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('')
1679 assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('')
1661 end
1680 end
1662 end
1681 end
General Comments 0
You need to be logged in to leave comments. Login now