##// END OF EJS Templates
Added tests for Issue#recipients...
Eric Davis -
r4103:a61ee73e691f
parent child
Show More
@@ -1,741 +1,765
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 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.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
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_visible_scope_for_anonymous
68 def test_visible_scope_for_anonymous
69 # Anonymous user should see issues of public projects only
69 # Anonymous user should see issues of public projects only
70 issues = Issue.visible(User.anonymous).all
70 issues = Issue.visible(User.anonymous).all
71 assert issues.any?
71 assert issues.any?
72 assert_nil issues.detect {|issue| !issue.project.is_public?}
72 assert_nil issues.detect {|issue| !issue.project.is_public?}
73 # Anonymous user should not see issues without permission
73 # Anonymous user should not see issues without permission
74 Role.anonymous.remove_permission!(:view_issues)
74 Role.anonymous.remove_permission!(:view_issues)
75 issues = Issue.visible(User.anonymous).all
75 issues = Issue.visible(User.anonymous).all
76 assert issues.empty?
76 assert issues.empty?
77 end
77 end
78
78
79 def test_visible_scope_for_user
79 def test_visible_scope_for_user
80 user = User.find(9)
80 user = User.find(9)
81 assert user.projects.empty?
81 assert user.projects.empty?
82 # Non member user should see issues of public projects only
82 # Non member user should see issues of public projects only
83 issues = Issue.visible(user).all
83 issues = Issue.visible(user).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 # Non member user should not see issues without permission
86 # Non member user should not see issues without permission
87 Role.non_member.remove_permission!(:view_issues)
87 Role.non_member.remove_permission!(:view_issues)
88 user.reload
88 user.reload
89 issues = Issue.visible(user).all
89 issues = Issue.visible(user).all
90 assert issues.empty?
90 assert issues.empty?
91 # User should see issues of projects for which he has view_issues permissions only
91 # User should see issues of projects for which he has view_issues permissions only
92 Member.create!(:principal => user, :project_id => 2, :role_ids => [1])
92 Member.create!(:principal => user, :project_id => 2, :role_ids => [1])
93 user.reload
93 user.reload
94 issues = Issue.visible(user).all
94 issues = Issue.visible(user).all
95 assert issues.any?
95 assert issues.any?
96 assert_nil issues.detect {|issue| issue.project_id != 2}
96 assert_nil issues.detect {|issue| issue.project_id != 2}
97 end
97 end
98
98
99 def test_visible_scope_for_admin
99 def test_visible_scope_for_admin
100 user = User.find(1)
100 user = User.find(1)
101 user.members.each(&:destroy)
101 user.members.each(&:destroy)
102 assert user.projects.empty?
102 assert user.projects.empty?
103 issues = Issue.visible(user).all
103 issues = Issue.visible(user).all
104 assert issues.any?
104 assert issues.any?
105 # Admin should see issues on private projects that he does not belong to
105 # Admin should see issues on private projects that he does not belong to
106 assert issues.detect {|issue| !issue.project.is_public?}
106 assert issues.detect {|issue| !issue.project.is_public?}
107 end
107 end
108
108
109 def test_errors_full_messages_should_include_custom_fields_errors
109 def test_errors_full_messages_should_include_custom_fields_errors
110 field = IssueCustomField.find_by_name('Database')
110 field = IssueCustomField.find_by_name('Database')
111
111
112 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')
112 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')
113 assert issue.available_custom_fields.include?(field)
113 assert issue.available_custom_fields.include?(field)
114 # Invalid value
114 # Invalid value
115 issue.custom_field_values = { field.id => 'SQLServer' }
115 issue.custom_field_values = { field.id => 'SQLServer' }
116
116
117 assert !issue.valid?
117 assert !issue.valid?
118 assert_equal 1, issue.errors.full_messages.size
118 assert_equal 1, issue.errors.full_messages.size
119 assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}", issue.errors.full_messages.first
119 assert_equal "Database #{I18n.translate('activerecord.errors.messages.inclusion')}", issue.errors.full_messages.first
120 end
120 end
121
121
122 def test_update_issue_with_required_custom_field
122 def test_update_issue_with_required_custom_field
123 field = IssueCustomField.find_by_name('Database')
123 field = IssueCustomField.find_by_name('Database')
124 field.update_attribute(:is_required, true)
124 field.update_attribute(:is_required, true)
125
125
126 issue = Issue.find(1)
126 issue = Issue.find(1)
127 assert_nil issue.custom_value_for(field)
127 assert_nil issue.custom_value_for(field)
128 assert issue.available_custom_fields.include?(field)
128 assert issue.available_custom_fields.include?(field)
129 # No change to custom values, issue can be saved
129 # No change to custom values, issue can be saved
130 assert issue.save
130 assert issue.save
131 # Blank value
131 # Blank value
132 issue.custom_field_values = { field.id => '' }
132 issue.custom_field_values = { field.id => '' }
133 assert !issue.save
133 assert !issue.save
134 # Valid value
134 # Valid value
135 issue.custom_field_values = { field.id => 'PostgreSQL' }
135 issue.custom_field_values = { field.id => 'PostgreSQL' }
136 assert issue.save
136 assert issue.save
137 issue.reload
137 issue.reload
138 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
138 assert_equal 'PostgreSQL', issue.custom_value_for(field).value
139 end
139 end
140
140
141 def test_should_not_update_attributes_if_custom_fields_validation_fails
141 def test_should_not_update_attributes_if_custom_fields_validation_fails
142 issue = Issue.find(1)
142 issue = Issue.find(1)
143 field = IssueCustomField.find_by_name('Database')
143 field = IssueCustomField.find_by_name('Database')
144 assert issue.available_custom_fields.include?(field)
144 assert issue.available_custom_fields.include?(field)
145
145
146 issue.custom_field_values = { field.id => 'Invalid' }
146 issue.custom_field_values = { field.id => 'Invalid' }
147 issue.subject = 'Should be not be saved'
147 issue.subject = 'Should be not be saved'
148 assert !issue.save
148 assert !issue.save
149
149
150 issue.reload
150 issue.reload
151 assert_equal "Can't print recipes", issue.subject
151 assert_equal "Can't print recipes", issue.subject
152 end
152 end
153
153
154 def test_should_not_recreate_custom_values_objects_on_update
154 def test_should_not_recreate_custom_values_objects_on_update
155 field = IssueCustomField.find_by_name('Database')
155 field = IssueCustomField.find_by_name('Database')
156
156
157 issue = Issue.find(1)
157 issue = Issue.find(1)
158 issue.custom_field_values = { field.id => 'PostgreSQL' }
158 issue.custom_field_values = { field.id => 'PostgreSQL' }
159 assert issue.save
159 assert issue.save
160 custom_value = issue.custom_value_for(field)
160 custom_value = issue.custom_value_for(field)
161 issue.reload
161 issue.reload
162 issue.custom_field_values = { field.id => 'MySQL' }
162 issue.custom_field_values = { field.id => 'MySQL' }
163 assert issue.save
163 assert issue.save
164 issue.reload
164 issue.reload
165 assert_equal custom_value.id, issue.custom_value_for(field).id
165 assert_equal custom_value.id, issue.custom_value_for(field).id
166 end
166 end
167
167
168 def test_assigning_tracker_id_should_reload_custom_fields_values
168 def test_assigning_tracker_id_should_reload_custom_fields_values
169 issue = Issue.new(:project => Project.find(1))
169 issue = Issue.new(:project => Project.find(1))
170 assert issue.custom_field_values.empty?
170 assert issue.custom_field_values.empty?
171 issue.tracker_id = 1
171 issue.tracker_id = 1
172 assert issue.custom_field_values.any?
172 assert issue.custom_field_values.any?
173 end
173 end
174
174
175 def test_assigning_attributes_should_assign_tracker_id_first
175 def test_assigning_attributes_should_assign_tracker_id_first
176 attributes = ActiveSupport::OrderedHash.new
176 attributes = ActiveSupport::OrderedHash.new
177 attributes['custom_field_values'] = { '1' => 'MySQL' }
177 attributes['custom_field_values'] = { '1' => 'MySQL' }
178 attributes['tracker_id'] = '1'
178 attributes['tracker_id'] = '1'
179 issue = Issue.new(:project => Project.find(1))
179 issue = Issue.new(:project => Project.find(1))
180 issue.attributes = attributes
180 issue.attributes = attributes
181 assert_not_nil issue.custom_value_for(1)
181 assert_not_nil issue.custom_value_for(1)
182 assert_equal 'MySQL', issue.custom_value_for(1).value
182 assert_equal 'MySQL', issue.custom_value_for(1).value
183 end
183 end
184
184
185 def test_should_update_issue_with_disabled_tracker
185 def test_should_update_issue_with_disabled_tracker
186 p = Project.find(1)
186 p = Project.find(1)
187 issue = Issue.find(1)
187 issue = Issue.find(1)
188
188
189 p.trackers.delete(issue.tracker)
189 p.trackers.delete(issue.tracker)
190 assert !p.trackers.include?(issue.tracker)
190 assert !p.trackers.include?(issue.tracker)
191
191
192 issue.reload
192 issue.reload
193 issue.subject = 'New subject'
193 issue.subject = 'New subject'
194 assert issue.save
194 assert issue.save
195 end
195 end
196
196
197 def test_should_not_set_a_disabled_tracker
197 def test_should_not_set_a_disabled_tracker
198 p = Project.find(1)
198 p = Project.find(1)
199 p.trackers.delete(Tracker.find(2))
199 p.trackers.delete(Tracker.find(2))
200
200
201 issue = Issue.find(1)
201 issue = Issue.find(1)
202 issue.tracker_id = 2
202 issue.tracker_id = 2
203 issue.subject = 'New subject'
203 issue.subject = 'New subject'
204 assert !issue.save
204 assert !issue.save
205 assert_not_nil issue.errors.on(:tracker_id)
205 assert_not_nil issue.errors.on(:tracker_id)
206 end
206 end
207
207
208 def test_category_based_assignment
208 def test_category_based_assignment
209 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)
209 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)
210 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
210 assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
211 end
211 end
212
212
213 def test_copy
213 def test_copy
214 issue = Issue.new.copy_from(1)
214 issue = Issue.new.copy_from(1)
215 assert issue.save
215 assert issue.save
216 issue.reload
216 issue.reload
217 orig = Issue.find(1)
217 orig = Issue.find(1)
218 assert_equal orig.subject, issue.subject
218 assert_equal orig.subject, issue.subject
219 assert_equal orig.tracker, issue.tracker
219 assert_equal orig.tracker, issue.tracker
220 assert_equal "125", issue.custom_value_for(2).value
220 assert_equal "125", issue.custom_value_for(2).value
221 end
221 end
222
222
223 def test_copy_should_copy_status
223 def test_copy_should_copy_status
224 orig = Issue.find(8)
224 orig = Issue.find(8)
225 assert orig.status != IssueStatus.default
225 assert orig.status != IssueStatus.default
226
226
227 issue = Issue.new.copy_from(orig)
227 issue = Issue.new.copy_from(orig)
228 assert issue.save
228 assert issue.save
229 issue.reload
229 issue.reload
230 assert_equal orig.status, issue.status
230 assert_equal orig.status, issue.status
231 end
231 end
232
232
233 def test_should_close_duplicates
233 def test_should_close_duplicates
234 # Create 3 issues
234 # Create 3 issues
235 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')
235 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')
236 assert issue1.save
236 assert issue1.save
237 issue2 = issue1.clone
237 issue2 = issue1.clone
238 assert issue2.save
238 assert issue2.save
239 issue3 = issue1.clone
239 issue3 = issue1.clone
240 assert issue3.save
240 assert issue3.save
241
241
242 # 2 is a dupe of 1
242 # 2 is a dupe of 1
243 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
243 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
244 # And 3 is a dupe of 2
244 # And 3 is a dupe of 2
245 IssueRelation.create(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
245 IssueRelation.create(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
246 # And 3 is a dupe of 1 (circular duplicates)
246 # And 3 is a dupe of 1 (circular duplicates)
247 IssueRelation.create(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
247 IssueRelation.create(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
248
248
249 assert issue1.reload.duplicates.include?(issue2)
249 assert issue1.reload.duplicates.include?(issue2)
250
250
251 # Closing issue 1
251 # Closing issue 1
252 issue1.init_journal(User.find(:first), "Closing issue1")
252 issue1.init_journal(User.find(:first), "Closing issue1")
253 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
253 issue1.status = IssueStatus.find :first, :conditions => {:is_closed => true}
254 assert issue1.save
254 assert issue1.save
255 # 2 and 3 should be also closed
255 # 2 and 3 should be also closed
256 assert issue2.reload.closed?
256 assert issue2.reload.closed?
257 assert issue3.reload.closed?
257 assert issue3.reload.closed?
258 end
258 end
259
259
260 def test_should_not_close_duplicated_issue
260 def test_should_not_close_duplicated_issue
261 # Create 3 issues
261 # Create 3 issues
262 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')
262 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')
263 assert issue1.save
263 assert issue1.save
264 issue2 = issue1.clone
264 issue2 = issue1.clone
265 assert issue2.save
265 assert issue2.save
266
266
267 # 2 is a dupe of 1
267 # 2 is a dupe of 1
268 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
268 IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
269 # 2 is a dup of 1 but 1 is not a duplicate of 2
269 # 2 is a dup of 1 but 1 is not a duplicate of 2
270 assert !issue2.reload.duplicates.include?(issue1)
270 assert !issue2.reload.duplicates.include?(issue1)
271
271
272 # Closing issue 2
272 # Closing issue 2
273 issue2.init_journal(User.find(:first), "Closing issue2")
273 issue2.init_journal(User.find(:first), "Closing issue2")
274 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
274 issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
275 assert issue2.save
275 assert issue2.save
276 # 1 should not be also closed
276 # 1 should not be also closed
277 assert !issue1.reload.closed?
277 assert !issue1.reload.closed?
278 end
278 end
279
279
280 def test_assignable_versions
280 def test_assignable_versions
281 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
281 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
282 assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
282 assert_equal ['open'], issue.assignable_versions.collect(&:status).uniq
283 end
283 end
284
284
285 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
285 def test_should_not_be_able_to_assign_a_new_issue_to_a_closed_version
286 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
286 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 1, :subject => 'New issue')
287 assert !issue.save
287 assert !issue.save
288 assert_not_nil issue.errors.on(:fixed_version_id)
288 assert_not_nil issue.errors.on(:fixed_version_id)
289 end
289 end
290
290
291 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
291 def test_should_not_be_able_to_assign_a_new_issue_to_a_locked_version
292 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
292 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 2, :subject => 'New issue')
293 assert !issue.save
293 assert !issue.save
294 assert_not_nil issue.errors.on(:fixed_version_id)
294 assert_not_nil issue.errors.on(:fixed_version_id)
295 end
295 end
296
296
297 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
297 def test_should_be_able_to_assign_a_new_issue_to_an_open_version
298 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
298 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :fixed_version_id => 3, :subject => 'New issue')
299 assert issue.save
299 assert issue.save
300 end
300 end
301
301
302 def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
302 def test_should_be_able_to_update_an_issue_assigned_to_a_closed_version
303 issue = Issue.find(11)
303 issue = Issue.find(11)
304 assert_equal 'closed', issue.fixed_version.status
304 assert_equal 'closed', issue.fixed_version.status
305 issue.subject = 'Subject changed'
305 issue.subject = 'Subject changed'
306 assert issue.save
306 assert issue.save
307 end
307 end
308
308
309 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
309 def test_should_not_be_able_to_reopen_an_issue_assigned_to_a_closed_version
310 issue = Issue.find(11)
310 issue = Issue.find(11)
311 issue.status_id = 1
311 issue.status_id = 1
312 assert !issue.save
312 assert !issue.save
313 assert_not_nil issue.errors.on_base
313 assert_not_nil issue.errors.on_base
314 end
314 end
315
315
316 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
316 def test_should_be_able_to_reopen_and_reassign_an_issue_assigned_to_a_closed_version
317 issue = Issue.find(11)
317 issue = Issue.find(11)
318 issue.status_id = 1
318 issue.status_id = 1
319 issue.fixed_version_id = 3
319 issue.fixed_version_id = 3
320 assert issue.save
320 assert issue.save
321 end
321 end
322
322
323 def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
323 def test_should_be_able_to_reopen_an_issue_assigned_to_a_locked_version
324 issue = Issue.find(12)
324 issue = Issue.find(12)
325 assert_equal 'locked', issue.fixed_version.status
325 assert_equal 'locked', issue.fixed_version.status
326 issue.status_id = 1
326 issue.status_id = 1
327 assert issue.save
327 assert issue.save
328 end
328 end
329
329
330 def test_move_to_another_project_with_same_category
330 def test_move_to_another_project_with_same_category
331 issue = Issue.find(1)
331 issue = Issue.find(1)
332 assert issue.move_to_project(Project.find(2))
332 assert issue.move_to_project(Project.find(2))
333 issue.reload
333 issue.reload
334 assert_equal 2, issue.project_id
334 assert_equal 2, issue.project_id
335 # Category changes
335 # Category changes
336 assert_equal 4, issue.category_id
336 assert_equal 4, issue.category_id
337 # Make sure time entries were move to the target project
337 # Make sure time entries were move to the target project
338 assert_equal 2, issue.time_entries.first.project_id
338 assert_equal 2, issue.time_entries.first.project_id
339 end
339 end
340
340
341 def test_move_to_another_project_without_same_category
341 def test_move_to_another_project_without_same_category
342 issue = Issue.find(2)
342 issue = Issue.find(2)
343 assert issue.move_to_project(Project.find(2))
343 assert issue.move_to_project(Project.find(2))
344 issue.reload
344 issue.reload
345 assert_equal 2, issue.project_id
345 assert_equal 2, issue.project_id
346 # Category cleared
346 # Category cleared
347 assert_nil issue.category_id
347 assert_nil issue.category_id
348 end
348 end
349
349
350 def test_move_to_another_project_should_clear_fixed_version_when_not_shared
350 def test_move_to_another_project_should_clear_fixed_version_when_not_shared
351 issue = Issue.find(1)
351 issue = Issue.find(1)
352 issue.update_attribute(:fixed_version_id, 1)
352 issue.update_attribute(:fixed_version_id, 1)
353 assert issue.move_to_project(Project.find(2))
353 assert issue.move_to_project(Project.find(2))
354 issue.reload
354 issue.reload
355 assert_equal 2, issue.project_id
355 assert_equal 2, issue.project_id
356 # Cleared fixed_version
356 # Cleared fixed_version
357 assert_equal nil, issue.fixed_version
357 assert_equal nil, issue.fixed_version
358 end
358 end
359
359
360 def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
360 def test_move_to_another_project_should_keep_fixed_version_when_shared_with_the_target_project
361 issue = Issue.find(1)
361 issue = Issue.find(1)
362 issue.update_attribute(:fixed_version_id, 4)
362 issue.update_attribute(:fixed_version_id, 4)
363 assert issue.move_to_project(Project.find(5))
363 assert issue.move_to_project(Project.find(5))
364 issue.reload
364 issue.reload
365 assert_equal 5, issue.project_id
365 assert_equal 5, issue.project_id
366 # Keep fixed_version
366 # Keep fixed_version
367 assert_equal 4, issue.fixed_version_id
367 assert_equal 4, issue.fixed_version_id
368 end
368 end
369
369
370 def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
370 def test_move_to_another_project_should_clear_fixed_version_when_not_shared_with_the_target_project
371 issue = Issue.find(1)
371 issue = Issue.find(1)
372 issue.update_attribute(:fixed_version_id, 1)
372 issue.update_attribute(:fixed_version_id, 1)
373 assert issue.move_to_project(Project.find(5))
373 assert issue.move_to_project(Project.find(5))
374 issue.reload
374 issue.reload
375 assert_equal 5, issue.project_id
375 assert_equal 5, issue.project_id
376 # Cleared fixed_version
376 # Cleared fixed_version
377 assert_equal nil, issue.fixed_version
377 assert_equal nil, issue.fixed_version
378 end
378 end
379
379
380 def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
380 def test_move_to_another_project_should_keep_fixed_version_when_shared_systemwide
381 issue = Issue.find(1)
381 issue = Issue.find(1)
382 issue.update_attribute(:fixed_version_id, 7)
382 issue.update_attribute(:fixed_version_id, 7)
383 assert issue.move_to_project(Project.find(2))
383 assert issue.move_to_project(Project.find(2))
384 issue.reload
384 issue.reload
385 assert_equal 2, issue.project_id
385 assert_equal 2, issue.project_id
386 # Keep fixed_version
386 # Keep fixed_version
387 assert_equal 7, issue.fixed_version_id
387 assert_equal 7, issue.fixed_version_id
388 end
388 end
389
389
390 def test_move_to_another_project_with_disabled_tracker
390 def test_move_to_another_project_with_disabled_tracker
391 issue = Issue.find(1)
391 issue = Issue.find(1)
392 target = Project.find(2)
392 target = Project.find(2)
393 target.tracker_ids = [3]
393 target.tracker_ids = [3]
394 target.save
394 target.save
395 assert_equal false, issue.move_to_project(target)
395 assert_equal false, issue.move_to_project(target)
396 issue.reload
396 issue.reload
397 assert_equal 1, issue.project_id
397 assert_equal 1, issue.project_id
398 end
398 end
399
399
400 def test_copy_to_the_same_project
400 def test_copy_to_the_same_project
401 issue = Issue.find(1)
401 issue = Issue.find(1)
402 copy = nil
402 copy = nil
403 assert_difference 'Issue.count' do
403 assert_difference 'Issue.count' do
404 copy = issue.move_to_project(issue.project, nil, :copy => true)
404 copy = issue.move_to_project(issue.project, nil, :copy => true)
405 end
405 end
406 assert_kind_of Issue, copy
406 assert_kind_of Issue, copy
407 assert_equal issue.project, copy.project
407 assert_equal issue.project, copy.project
408 assert_equal "125", copy.custom_value_for(2).value
408 assert_equal "125", copy.custom_value_for(2).value
409 end
409 end
410
410
411 def test_copy_to_another_project_and_tracker
411 def test_copy_to_another_project_and_tracker
412 issue = Issue.find(1)
412 issue = Issue.find(1)
413 copy = nil
413 copy = nil
414 assert_difference 'Issue.count' do
414 assert_difference 'Issue.count' do
415 copy = issue.move_to_project(Project.find(3), Tracker.find(2), :copy => true)
415 copy = issue.move_to_project(Project.find(3), Tracker.find(2), :copy => true)
416 end
416 end
417 copy.reload
417 copy.reload
418 assert_kind_of Issue, copy
418 assert_kind_of Issue, copy
419 assert_equal Project.find(3), copy.project
419 assert_equal Project.find(3), copy.project
420 assert_equal Tracker.find(2), copy.tracker
420 assert_equal Tracker.find(2), copy.tracker
421 # Custom field #2 is not associated with target tracker
421 # Custom field #2 is not associated with target tracker
422 assert_nil copy.custom_value_for(2)
422 assert_nil copy.custom_value_for(2)
423 end
423 end
424
424
425 context "#move_to_project" do
425 context "#move_to_project" do
426 context "as a copy" do
426 context "as a copy" do
427 setup do
427 setup do
428 @issue = Issue.find(1)
428 @issue = Issue.find(1)
429 @copy = nil
429 @copy = nil
430 end
430 end
431
431
432 should "allow assigned_to changes" do
432 should "allow assigned_to changes" do
433 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
433 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:assigned_to_id => 3}})
434 assert_equal 3, @copy.assigned_to_id
434 assert_equal 3, @copy.assigned_to_id
435 end
435 end
436
436
437 should "allow status changes" do
437 should "allow status changes" do
438 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:status_id => 2}})
438 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:status_id => 2}})
439 assert_equal 2, @copy.status_id
439 assert_equal 2, @copy.status_id
440 end
440 end
441
441
442 should "allow start date changes" do
442 should "allow start date changes" do
443 date = Date.today
443 date = Date.today
444 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
444 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:start_date => date}})
445 assert_equal date, @copy.start_date
445 assert_equal date, @copy.start_date
446 end
446 end
447
447
448 should "allow due date changes" do
448 should "allow due date changes" do
449 date = Date.today
449 date = Date.today
450 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:due_date => date}})
450 @copy = @issue.move_to_project(Project.find(3), Tracker.find(2), {:copy => true, :attributes => {:due_date => date}})
451
451
452 assert_equal date, @copy.due_date
452 assert_equal date, @copy.due_date
453 end
453 end
454 end
454 end
455 end
455 end
456
456
457 def test_recipients_should_not_include_users_that_cannot_view_the_issue
457 def test_recipients_should_not_include_users_that_cannot_view_the_issue
458 issue = Issue.find(12)
458 issue = Issue.find(12)
459 assert issue.recipients.include?(issue.author.mail)
459 assert issue.recipients.include?(issue.author.mail)
460 # move the issue to a private project
460 # move the issue to a private project
461 copy = issue.move_to_project(Project.find(5), Tracker.find(2), :copy => true)
461 copy = issue.move_to_project(Project.find(5), Tracker.find(2), :copy => true)
462 # author is not a member of project anymore
462 # author is not a member of project anymore
463 assert !copy.recipients.include?(copy.author.mail)
463 assert !copy.recipients.include?(copy.author.mail)
464 end
464 end
465
465
466 def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
466 def test_watcher_recipients_should_not_include_users_that_cannot_view_the_issue
467 user = User.find(3)
467 user = User.find(3)
468 issue = Issue.find(9)
468 issue = Issue.find(9)
469 Watcher.create!(:user => user, :watchable => issue)
469 Watcher.create!(:user => user, :watchable => issue)
470 assert issue.watched_by?(user)
470 assert issue.watched_by?(user)
471 assert !issue.watcher_recipients.include?(user.mail)
471 assert !issue.watcher_recipients.include?(user.mail)
472 end
472 end
473
473
474 def test_issue_destroy
474 def test_issue_destroy
475 Issue.find(1).destroy
475 Issue.find(1).destroy
476 assert_nil Issue.find_by_id(1)
476 assert_nil Issue.find_by_id(1)
477 assert_nil TimeEntry.find_by_issue_id(1)
477 assert_nil TimeEntry.find_by_issue_id(1)
478 end
478 end
479
479
480 def test_blocked
480 def test_blocked
481 blocked_issue = Issue.find(9)
481 blocked_issue = Issue.find(9)
482 blocking_issue = Issue.find(10)
482 blocking_issue = Issue.find(10)
483
483
484 assert blocked_issue.blocked?
484 assert blocked_issue.blocked?
485 assert !blocking_issue.blocked?
485 assert !blocking_issue.blocked?
486 end
486 end
487
487
488 def test_blocked_issues_dont_allow_closed_statuses
488 def test_blocked_issues_dont_allow_closed_statuses
489 blocked_issue = Issue.find(9)
489 blocked_issue = Issue.find(9)
490
490
491 allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
491 allowed_statuses = blocked_issue.new_statuses_allowed_to(users(:users_002))
492 assert !allowed_statuses.empty?
492 assert !allowed_statuses.empty?
493 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
493 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
494 assert closed_statuses.empty?
494 assert closed_statuses.empty?
495 end
495 end
496
496
497 def test_unblocked_issues_allow_closed_statuses
497 def test_unblocked_issues_allow_closed_statuses
498 blocking_issue = Issue.find(10)
498 blocking_issue = Issue.find(10)
499
499
500 allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
500 allowed_statuses = blocking_issue.new_statuses_allowed_to(users(:users_002))
501 assert !allowed_statuses.empty?
501 assert !allowed_statuses.empty?
502 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
502 closed_statuses = allowed_statuses.select {|st| st.is_closed?}
503 assert !closed_statuses.empty?
503 assert !closed_statuses.empty?
504 end
504 end
505
505
506 def test_overdue
506 def test_overdue
507 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
507 assert Issue.new(:due_date => 1.day.ago.to_date).overdue?
508 assert !Issue.new(:due_date => Date.today).overdue?
508 assert !Issue.new(:due_date => Date.today).overdue?
509 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
509 assert !Issue.new(:due_date => 1.day.from_now.to_date).overdue?
510 assert !Issue.new(:due_date => nil).overdue?
510 assert !Issue.new(:due_date => nil).overdue?
511 assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
511 assert !Issue.new(:due_date => 1.day.ago.to_date, :status => IssueStatus.find(:first, :conditions => {:is_closed => true})).overdue?
512 end
512 end
513
513
514 context "#behind_schedule?" do
514 context "#behind_schedule?" do
515 should "be false if the issue has no start_date" do
515 should "be false if the issue has no start_date" do
516 assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
516 assert !Issue.new(:start_date => nil, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
517 end
517 end
518
518
519 should "be false if the issue has no end_date" do
519 should "be false if the issue has no end_date" do
520 assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
520 assert !Issue.new(:start_date => 1.day.from_now.to_date, :due_date => nil, :done_ratio => 0).behind_schedule?
521 end
521 end
522
522
523 should "be false if the issue has more done than it's calendar time" do
523 should "be false if the issue has more done than it's calendar time" do
524 assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
524 assert !Issue.new(:start_date => 50.days.ago.to_date, :due_date => 50.days.from_now.to_date, :done_ratio => 90).behind_schedule?
525 end
525 end
526
526
527 should "be true if the issue hasn't been started at all" do
527 should "be true if the issue hasn't been started at all" do
528 assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
528 assert Issue.new(:start_date => 1.day.ago.to_date, :due_date => 1.day.from_now.to_date, :done_ratio => 0).behind_schedule?
529 end
529 end
530
530
531 should "be true if the issue has used more calendar time than it's done ratio" do
531 should "be true if the issue has used more calendar time than it's done ratio" do
532 assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
532 assert Issue.new(:start_date => 100.days.ago.to_date, :due_date => Date.today, :done_ratio => 90).behind_schedule?
533 end
533 end
534 end
534 end
535
535
536 def test_assignable_users
536 def test_assignable_users
537 assert_kind_of User, Issue.find(1).assignable_users.first
537 assert_kind_of User, Issue.find(1).assignable_users.first
538 end
538 end
539
539
540 def test_create_should_send_email_notification
540 def test_create_should_send_email_notification
541 ActionMailer::Base.deliveries.clear
541 ActionMailer::Base.deliveries.clear
542 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')
542 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')
543
543
544 assert issue.save
544 assert issue.save
545 assert_equal 1, ActionMailer::Base.deliveries.size
545 assert_equal 1, ActionMailer::Base.deliveries.size
546 end
546 end
547
547
548 def test_stale_issue_should_not_send_email_notification
548 def test_stale_issue_should_not_send_email_notification
549 ActionMailer::Base.deliveries.clear
549 ActionMailer::Base.deliveries.clear
550 issue = Issue.find(1)
550 issue = Issue.find(1)
551 stale = Issue.find(1)
551 stale = Issue.find(1)
552
552
553 issue.init_journal(User.find(1))
553 issue.init_journal(User.find(1))
554 issue.subject = 'Subjet update'
554 issue.subject = 'Subjet update'
555 assert issue.save
555 assert issue.save
556 assert_equal 1, ActionMailer::Base.deliveries.size
556 assert_equal 1, ActionMailer::Base.deliveries.size
557 ActionMailer::Base.deliveries.clear
557 ActionMailer::Base.deliveries.clear
558
558
559 stale.init_journal(User.find(1))
559 stale.init_journal(User.find(1))
560 stale.subject = 'Another subjet update'
560 stale.subject = 'Another subjet update'
561 assert_raise ActiveRecord::StaleObjectError do
561 assert_raise ActiveRecord::StaleObjectError do
562 stale.save
562 stale.save
563 end
563 end
564 assert ActionMailer::Base.deliveries.empty?
564 assert ActionMailer::Base.deliveries.empty?
565 end
565 end
566
566
567 def test_saving_twice_should_not_duplicate_journal_details
567 def test_saving_twice_should_not_duplicate_journal_details
568 i = Issue.find(:first)
568 i = Issue.find(:first)
569 i.init_journal(User.find(2), 'Some notes')
569 i.init_journal(User.find(2), 'Some notes')
570 # initial changes
570 # initial changes
571 i.subject = 'New subject'
571 i.subject = 'New subject'
572 i.done_ratio = i.done_ratio + 10
572 i.done_ratio = i.done_ratio + 10
573 assert_difference 'Journal.count' do
573 assert_difference 'Journal.count' do
574 assert i.save
574 assert i.save
575 end
575 end
576 # 1 more change
576 # 1 more change
577 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
577 i.priority = IssuePriority.find(:first, :conditions => ["id <> ?", i.priority_id])
578 assert_no_difference 'Journal.count' do
578 assert_no_difference 'Journal.count' do
579 assert_difference 'JournalDetail.count', 1 do
579 assert_difference 'JournalDetail.count', 1 do
580 i.save
580 i.save
581 end
581 end
582 end
582 end
583 # no more change
583 # no more change
584 assert_no_difference 'Journal.count' do
584 assert_no_difference 'Journal.count' do
585 assert_no_difference 'JournalDetail.count' do
585 assert_no_difference 'JournalDetail.count' do
586 i.save
586 i.save
587 end
587 end
588 end
588 end
589 end
589 end
590
590
591 context "#done_ratio" do
591 context "#done_ratio" do
592 setup do
592 setup do
593 @issue = Issue.find(1)
593 @issue = Issue.find(1)
594 @issue_status = IssueStatus.find(1)
594 @issue_status = IssueStatus.find(1)
595 @issue_status.update_attribute(:default_done_ratio, 50)
595 @issue_status.update_attribute(:default_done_ratio, 50)
596 @issue2 = Issue.find(2)
596 @issue2 = Issue.find(2)
597 @issue_status2 = IssueStatus.find(2)
597 @issue_status2 = IssueStatus.find(2)
598 @issue_status2.update_attribute(:default_done_ratio, 0)
598 @issue_status2.update_attribute(:default_done_ratio, 0)
599 end
599 end
600
600
601 context "with Setting.issue_done_ratio using the issue_field" do
601 context "with Setting.issue_done_ratio using the issue_field" do
602 setup do
602 setup do
603 Setting.issue_done_ratio = 'issue_field'
603 Setting.issue_done_ratio = 'issue_field'
604 end
604 end
605
605
606 should "read the issue's field" do
606 should "read the issue's field" do
607 assert_equal 0, @issue.done_ratio
607 assert_equal 0, @issue.done_ratio
608 assert_equal 30, @issue2.done_ratio
608 assert_equal 30, @issue2.done_ratio
609 end
609 end
610 end
610 end
611
611
612 context "with Setting.issue_done_ratio using the issue_status" do
612 context "with Setting.issue_done_ratio using the issue_status" do
613 setup do
613 setup do
614 Setting.issue_done_ratio = 'issue_status'
614 Setting.issue_done_ratio = 'issue_status'
615 end
615 end
616
616
617 should "read the Issue Status's default done ratio" do
617 should "read the Issue Status's default done ratio" do
618 assert_equal 50, @issue.done_ratio
618 assert_equal 50, @issue.done_ratio
619 assert_equal 0, @issue2.done_ratio
619 assert_equal 0, @issue2.done_ratio
620 end
620 end
621 end
621 end
622 end
622 end
623
623
624 context "#update_done_ratio_from_issue_status" do
624 context "#update_done_ratio_from_issue_status" do
625 setup do
625 setup do
626 @issue = Issue.find(1)
626 @issue = Issue.find(1)
627 @issue_status = IssueStatus.find(1)
627 @issue_status = IssueStatus.find(1)
628 @issue_status.update_attribute(:default_done_ratio, 50)
628 @issue_status.update_attribute(:default_done_ratio, 50)
629 @issue2 = Issue.find(2)
629 @issue2 = Issue.find(2)
630 @issue_status2 = IssueStatus.find(2)
630 @issue_status2 = IssueStatus.find(2)
631 @issue_status2.update_attribute(:default_done_ratio, 0)
631 @issue_status2.update_attribute(:default_done_ratio, 0)
632 end
632 end
633
633
634 context "with Setting.issue_done_ratio using the issue_field" do
634 context "with Setting.issue_done_ratio using the issue_field" do
635 setup do
635 setup do
636 Setting.issue_done_ratio = 'issue_field'
636 Setting.issue_done_ratio = 'issue_field'
637 end
637 end
638
638
639 should "not change the issue" do
639 should "not change the issue" do
640 @issue.update_done_ratio_from_issue_status
640 @issue.update_done_ratio_from_issue_status
641 @issue2.update_done_ratio_from_issue_status
641 @issue2.update_done_ratio_from_issue_status
642
642
643 assert_equal 0, @issue.read_attribute(:done_ratio)
643 assert_equal 0, @issue.read_attribute(:done_ratio)
644 assert_equal 30, @issue2.read_attribute(:done_ratio)
644 assert_equal 30, @issue2.read_attribute(:done_ratio)
645 end
645 end
646 end
646 end
647
647
648 context "with Setting.issue_done_ratio using the issue_status" do
648 context "with Setting.issue_done_ratio using the issue_status" do
649 setup do
649 setup do
650 Setting.issue_done_ratio = 'issue_status'
650 Setting.issue_done_ratio = 'issue_status'
651 end
651 end
652
652
653 should "change the issue's done ratio" do
653 should "change the issue's done ratio" do
654 @issue.update_done_ratio_from_issue_status
654 @issue.update_done_ratio_from_issue_status
655 @issue2.update_done_ratio_from_issue_status
655 @issue2.update_done_ratio_from_issue_status
656
656
657 assert_equal 50, @issue.read_attribute(:done_ratio)
657 assert_equal 50, @issue.read_attribute(:done_ratio)
658 assert_equal 0, @issue2.read_attribute(:done_ratio)
658 assert_equal 0, @issue2.read_attribute(:done_ratio)
659 end
659 end
660 end
660 end
661 end
661 end
662
662
663 test "#by_tracker" do
663 test "#by_tracker" do
664 groups = Issue.by_tracker(Project.find(1))
664 groups = Issue.by_tracker(Project.find(1))
665 assert_equal 3, groups.size
665 assert_equal 3, groups.size
666 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
666 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
667 end
667 end
668
668
669 test "#by_version" do
669 test "#by_version" do
670 groups = Issue.by_version(Project.find(1))
670 groups = Issue.by_version(Project.find(1))
671 assert_equal 3, groups.size
671 assert_equal 3, groups.size
672 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
672 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
673 end
673 end
674
674
675 test "#by_priority" do
675 test "#by_priority" do
676 groups = Issue.by_priority(Project.find(1))
676 groups = Issue.by_priority(Project.find(1))
677 assert_equal 4, groups.size
677 assert_equal 4, groups.size
678 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
678 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
679 end
679 end
680
680
681 test "#by_category" do
681 test "#by_category" do
682 groups = Issue.by_category(Project.find(1))
682 groups = Issue.by_category(Project.find(1))
683 assert_equal 2, groups.size
683 assert_equal 2, groups.size
684 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
684 assert_equal 3, groups.inject(0) {|sum, group| sum + group['total'].to_i}
685 end
685 end
686
686
687 test "#by_assigned_to" do
687 test "#by_assigned_to" do
688 groups = Issue.by_assigned_to(Project.find(1))
688 groups = Issue.by_assigned_to(Project.find(1))
689 assert_equal 2, groups.size
689 assert_equal 2, groups.size
690 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
690 assert_equal 2, groups.inject(0) {|sum, group| sum + group['total'].to_i}
691 end
691 end
692
692
693 test "#by_author" do
693 test "#by_author" do
694 groups = Issue.by_author(Project.find(1))
694 groups = Issue.by_author(Project.find(1))
695 assert_equal 4, groups.size
695 assert_equal 4, groups.size
696 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
696 assert_equal 7, groups.inject(0) {|sum, group| sum + group['total'].to_i}
697 end
697 end
698
698
699 test "#by_subproject" do
699 test "#by_subproject" do
700 groups = Issue.by_subproject(Project.find(1))
700 groups = Issue.by_subproject(Project.find(1))
701 assert_equal 2, groups.size
701 assert_equal 2, groups.size
702 assert_equal 5, groups.inject(0) {|sum, group| sum + group['total'].to_i}
702 assert_equal 5, groups.inject(0) {|sum, group| sum + group['total'].to_i}
703 end
703 end
704
704
705
705
706 context ".allowed_target_projects_on_move" do
706 context ".allowed_target_projects_on_move" do
707 should "return all active projects for admin users" do
707 should "return all active projects for admin users" do
708 User.current = User.find(1)
708 User.current = User.find(1)
709 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
709 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
710 end
710 end
711
711
712 should "return allowed projects for non admin users" do
712 should "return allowed projects for non admin users" do
713 User.current = User.find(2)
713 User.current = User.find(2)
714 Role.non_member.remove_permission! :move_issues
714 Role.non_member.remove_permission! :move_issues
715 assert_equal 3, Issue.allowed_target_projects_on_move.size
715 assert_equal 3, Issue.allowed_target_projects_on_move.size
716
716
717 Role.non_member.add_permission! :move_issues
717 Role.non_member.add_permission! :move_issues
718 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
718 assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
719 end
719 end
720 end
720 end
721
721
722 def test_recently_updated_with_limit_scopes
722 def test_recently_updated_with_limit_scopes
723 #should return the last updated issue
723 #should return the last updated issue
724 assert_equal 1, Issue.recently_updated.with_limit(1).length
724 assert_equal 1, Issue.recently_updated.with_limit(1).length
725 assert_equal Issue.find(:first, :order => "updated_on DESC"), Issue.recently_updated.with_limit(1).first
725 assert_equal Issue.find(:first, :order => "updated_on DESC"), Issue.recently_updated.with_limit(1).first
726 end
726 end
727
727
728 def test_on_active_projects_scope
728 def test_on_active_projects_scope
729 assert Project.find(2).archive
729 assert Project.find(2).archive
730
730
731 before = Issue.on_active_project.length
731 before = Issue.on_active_project.length
732 # test inclusion to results
732 # test inclusion to results
733 issue = Issue.generate_for_project!(Project.find(1), :tracker => Project.find(2).trackers.first)
733 issue = Issue.generate_for_project!(Project.find(1), :tracker => Project.find(2).trackers.first)
734 assert_equal before + 1, Issue.on_active_project.length
734 assert_equal before + 1, Issue.on_active_project.length
735
735
736 # Move to an archived project
736 # Move to an archived project
737 issue.project = Project.find(2)
737 issue.project = Project.find(2)
738 assert issue.save
738 assert issue.save
739 assert_equal before, Issue.on_active_project.length
739 assert_equal before, Issue.on_active_project.length
740 end
740 end
741
742 context "Issue#recipients" do
743 setup do
744 @project = Project.find(1)
745 @issue = Issue.generate_for_project!(@project, :assigned_to => User.generate_with_protected!)
746 end
747
748 should "include project recipients" do
749 assert @project.recipients.present?
750 @project.recipients.each do |project_recipient|
751 assert @issue.recipients.include?(project_recipient)
752 end
753 end
754
755 should "include the author if the author is active" do
756 assert @issue.author, "No author set for Issue"
757 assert @issue.recipients.include?(@issue.author.mail)
758 end
759
760 should "include the assigned to user if the assigned to user is active" do
761 assert @issue.assigned_to, "No assigned_to set for Issue"
762 assert @issue.recipients.include?(@issue.assigned_to.mail)
763 end
764 end
741 end
765 end
General Comments 0
You need to be logged in to leave comments. Login now