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