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