@@ -124,6 +124,28 class Issue < ActiveRecord::Base | |||||
124 | end |
|
124 | end | |
125 | end |
|
125 | end | |
126 |
|
126 | |||
|
127 | # AR#Persistence#destroy would raise and RecordNotFound exception | |||
|
128 | # if the issue was already deleted or updated (non matching lock_version). | |||
|
129 | # This is a problem when bulk deleting issues or deleting a project | |||
|
130 | # (because an issue may already be deleted if its parent was deleted | |||
|
131 | # first). | |||
|
132 | # The issue is reloaded by the nested_set before being deleted so | |||
|
133 | # the lock_version condition should not be an issue but we handle it. | |||
|
134 | def destroy | |||
|
135 | super | |||
|
136 | rescue ActiveRecord::RecordNotFound | |||
|
137 | # Stale or already deleted | |||
|
138 | begin | |||
|
139 | reload | |||
|
140 | rescue ActiveRecord::RecordNotFound | |||
|
141 | # The issue was actually already deleted | |||
|
142 | @destroyed = true | |||
|
143 | return freeze | |||
|
144 | end | |||
|
145 | # The issue was stale, retry to destroy | |||
|
146 | super | |||
|
147 | end | |||
|
148 | ||||
127 | # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields |
|
149 | # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields | |
128 | def available_custom_fields |
|
150 | def available_custom_fields | |
129 | (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : [] |
|
151 | (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : [] |
@@ -761,6 +761,30 class IssueTest < ActiveSupport::TestCase | |||||
761 | assert_nil TimeEntry.find_by_issue_id(1) |
|
761 | assert_nil TimeEntry.find_by_issue_id(1) | |
762 | end |
|
762 | end | |
763 |
|
763 | |||
|
764 | def test_destroying_a_deleted_issue_should_not_raise_an_error | |||
|
765 | issue = Issue.find(1) | |||
|
766 | Issue.find(1).destroy | |||
|
767 | ||||
|
768 | assert_nothing_raised do | |||
|
769 | assert_no_difference 'Issue.count' do | |||
|
770 | issue.destroy | |||
|
771 | end | |||
|
772 | assert issue.destroyed? | |||
|
773 | end | |||
|
774 | end | |||
|
775 | ||||
|
776 | def test_destroying_a_stale_issue_should_not_raise_an_error | |||
|
777 | issue = Issue.find(1) | |||
|
778 | Issue.find(1).update_attribute :subject, "Updated" | |||
|
779 | ||||
|
780 | assert_nothing_raised do | |||
|
781 | assert_difference 'Issue.count', -1 do | |||
|
782 | issue.destroy | |||
|
783 | end | |||
|
784 | assert issue.destroyed? | |||
|
785 | end | |||
|
786 | end | |||
|
787 | ||||
764 | def test_blocked |
|
788 | def test_blocked | |
765 | blocked_issue = Issue.find(9) |
|
789 | blocked_issue = Issue.find(9) | |
766 | blocking_issue = Issue.find(10) |
|
790 | blocking_issue = Issue.find(10) |
@@ -190,6 +190,18 class ProjectTest < ActiveSupport::TestCase | |||||
190 | assert_nil Issue.first(:conditions => {:project_id => @ecookbook.id}) |
|
190 | assert_nil Issue.first(:conditions => {:project_id => @ecookbook.id}) | |
191 | end |
|
191 | end | |
192 |
|
192 | |||
|
193 | def test_destroy_should_destroy_subtasks | |||
|
194 | issues = (0..2).to_a.map {Issue.create!(:project_id => 1, :tracker_id => 1, :author_id => 1, :subject => 'test')} | |||
|
195 | issues[0].update_attribute :parent_issue_id, issues[1].id | |||
|
196 | issues[2].update_attribute :parent_issue_id, issues[1].id | |||
|
197 | assert_equal 2, issues[1].children.count | |||
|
198 | ||||
|
199 | assert_nothing_raised do | |||
|
200 | Project.find(1).destroy | |||
|
201 | end | |||
|
202 | assert Issue.find_all_by_id(issues.map(&:id)).empty? | |||
|
203 | end | |||
|
204 | ||||
193 | def test_destroying_root_projects_should_clear_data |
|
205 | def test_destroying_root_projects_should_clear_data | |
194 | Project.roots.each do |root| |
|
206 | Project.roots.each do |root| | |
195 | root.destroy |
|
207 | root.destroy |
General Comments 0
You need to be logged in to leave comments.
Login now