Project

General

Profile

Feature #6033 » 6033_subtasks_show_in_parent_history-v2.patch

Yuichi HARADA, 2021-10-05 02:29

View differences:

app/helpers/issues_helper.rb
547 547
        value = "##{detail.value}" unless detail.value.blank?
548 548
        old_value = "##{detail.old_value}" unless detail.old_value.blank?
549 549

  
550
      when 'child_id'
551
        label = l(:label_subtask)
552
        value = "##{detail.value}" unless detail.value.blank?
553
        old_value = "##{detail.old_value}" unless detail.old_value.blank?
554
        multiple = true
555

  
550 556
      when 'is_private'
551 557
        value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank?
552 558
        old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank?
app/models/issue.rb
118 118
  after_save :reschedule_following_issues, :update_nested_set_attributes,
119 119
             :update_parent_attributes, :delete_selected_attachments, :create_journal
120 120
  # Should be after_create but would be called before previous after_save callbacks
121
  after_save :after_create_from_copy
122
  after_destroy :update_parent_attributes
121
  after_save :after_create_from_copy, :create_parent_issue_journal
122
  after_destroy :update_parent_attributes, :create_parent_issue_journal
123 123
  after_create_commit :send_notification
124 124

  
125 125
  # Returns a SQL conditions string used to find all issues visible by the specified user
......
1988 1988
    end
1989 1989
  end
1990 1990

  
1991
  def create_parent_issue_journal
1992
    return if persisted? && !saved_change_to_parent_id?
1993
    return if destroyed? && @without_nested_set_update
1994

  
1995
    child_id = self.id
1996
    old_parent_id, new_parent_id =
1997
      if persisted?
1998
        [parent_id_before_last_save, parent_id]
1999
      elsif destroyed?
2000
        [parent_id, nil]
2001
      else
2002
        [nil, parent_id]
2003
      end
2004

  
2005
    if old_parent_id.present? && old_parent_issue = Issue.visible.find_by_id(old_parent_id)
2006
      old_parent_issue.init_journal(User.current)
2007
      old_parent_issue.current_journal.__send__(:add_attribute_detail, 'child_id', child_id, nil)
2008
      old_parent_issue.save
2009
    end
2010
    if new_parent_id.present? && new_parent_issue = Issue.visible.find_by_id(new_parent_id)
2011
      new_parent_issue.init_journal(User.current)
2012
      new_parent_issue.current_journal.__send__(:add_attribute_detail, 'child_id', nil, child_id)
2013
      new_parent_issue.save
2014
    end
2015
  end
2016

  
1991 2017
  def send_notification
1992 2018
    if notify? && Setting.notified_events.include?('issue_added')
1993 2019
      Mailer.deliver_issue_add(self)
config/locales/en.yml
995 995
  label_missing_api_access_key: Missing an API access key
996 996
  label_api_access_key_created_on: "API access key created %{value} ago"
997 997
  label_profile: Profile
998
  label_subtask: Subtask
998 999
  label_subtask_plural: Subtasks
999 1000
  label_project_copy_notifications: Send email notifications during the project copy
1000 1001
  label_import_notifications: Send email notifications during the import
test/functional/issues_controller_test.rb
2344 2344
  end
2345 2345

  
2346 2346
  def test_show_should_list_subtasks
2347
    Issue.
2347
    issue = Issue.
2348 2348
      create!(
2349 2349
        :project_id => 1, :author_id => 1, :tracker_id => 1,
2350 2350
        :parent_issue_id => 1, :subject => 'Child Issue'
......
2354 2354
    assert_select 'div#issue_tree' do
2355 2355
      assert_select 'td.subject', :text => /Child Issue/
2356 2356
    end
2357
    assert_select 'div#tab-content-history' do
2358
      assert_select 'div[id=?]', "change-#{Issue.find(1).journals.last.id}" do
2359
        assert_select 'ul.details', :text => "Subtask ##{issue.id} added"
2360
      end
2361
    end
2357 2362
  end
2358 2363

  
2359 2364
  def test_show_should_show_subtasks_stats
......
8199 8204
    assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
8200 8205
  end
8201 8206

  
8207
  def test_destroy_child_issue
8208
    parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
8209
    child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
8210
    assert child.is_descendant_of?(parent.reload)
8211

  
8212
    @request.session[:user_id] = 2
8213
    assert_difference 'Issue.count', -1 do
8214
      delete :destroy, :params => {:id => child.id}
8215
    end
8216
    assert_response :found
8217
    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
8218

  
8219
    parent.reload
8220
    assert_equal 2, parent.journals.count
8221

  
8222
    get :show, :params => {:id => parent.id}
8223
    assert_response :success
8224

  
8225
    assert_select 'div#tab-content-history' do
8226
      assert_select 'div[id=?]', "change-#{parent.journals.last.id}" do
8227
        assert_select 'ul.details', :text => "Subtask deleted (##{child.id})"
8228
      end
8229
    end
8230
  end
8231

  
8202 8232
  def test_destroy_parent_and_child_issues
8203 8233
    parent = Issue.create!(:project_id => 1, :author_id => 1,
8204 8234
                           :tracker_id => 1, :subject => 'Parent Issue')
test/unit/issue_nested_set_test.rb
49 49
  def test_create_child_issue
50 50
    lft = new_issue_lft
51 51
    parent = Issue.generate!
52
    child =  parent.generate_child!
52
    child = nil
53
    assert_difference 'Journal.count', 1 do
54
      child = parent.generate_child!
55
    end
53 56
    parent.reload
54 57
    child.reload
55 58
    assert_equal [parent.id, nil,       lft,     lft + 3], [parent.root_id, parent.parent_id, parent.lft, parent.rgt]
......
58 61

  
59 62
  def test_creating_a_child_in_a_subproject_should_validate
60 63
    issue = Issue.generate!
61
    child = Issue.new(:project_id => 3, :tracker_id => 2, :author_id => 1,
62
                      :subject => 'child', :parent_issue_id => issue.id)
63
    assert_save child
64
    child = nil
65
    assert_difference 'Journal.count', 1 do
66
      child = Issue.new(:project_id => 3, :tracker_id => 2, :author_id => 1,
67
                        :subject => 'child', :parent_issue_id => issue.id)
68
      assert_save child
69
    end
64 70
    assert_equal issue, child.reload.parent
65 71
  end
66 72

  
67 73
  def test_creating_a_child_in_an_invalid_project_should_not_validate
68 74
    issue = Issue.generate!
69
    child = Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
70
                      :subject => 'child', :parent_issue_id => issue.id)
71
    assert !child.save
75
    child = nil
76
    assert_no_difference 'Journal.count' do
77
      child = Issue.new(:project_id => 2, :tracker_id => 1, :author_id => 1,
78
                        :subject => 'child', :parent_issue_id => issue.id)
79
      assert !child.save
80
    end
72 81
    assert_not_equal [], child.errors[:parent_issue_id]
73 82
  end
74 83

  
......
77 86
    parent1 = Issue.generate!
78 87
    parent2 = Issue.generate!
79 88
    child = parent1.generate_child!
80
    parent2.parent_issue_id = parent1.id
81
    parent2.save!
89
    assert_difference 'Journal.count', 2 do
90
      parent2.init_journal(User.find(2))
91
      parent2.parent_issue_id = parent1.id
92
      parent2.save!
93
    end
82 94
    child.reload
83 95
    parent1.reload
84 96
    parent2.reload
......
94 106
    parent2 = Issue.generate!
95 107
    lft3 = new_issue_lft
96 108
    child = parent1.generate_child!
97
    child.parent_issue_id = nil
98
    child.save!
109
    assert_difference 'Journal.count', 2 do
110
      child.init_journal(User.find(2))
111
      child.parent_issue_id = nil
112
      child.save!
113
    end
99 114
    child.reload
100 115
    parent1.reload
101 116
    parent2.reload
......
110 125
    lft2 = new_issue_lft
111 126
    parent2 = Issue.generate!
112 127
    child = parent1.generate_child!
113
    child.parent_issue_id = parent2.id
114
    child.save!
128
    assert_difference 'Journal.count', 3 do
129
      child.init_journal(User.find(2))
130
      child.parent_issue_id = parent2.id
131
      child.save!
132
    end
115 133
    child.reload
116 134
    parent1.reload
117 135
    parent2.reload
......
154 172
    grandchild = child.generate_child!
155 173
    lft4 = new_issue_lft
156 174
    child.reload
157
    child.project = Project.find(2)
158
    assert child.save
175
    assert_difference 'Journal.count', 2 do
176
      assert_difference 'JournalDetail.count', 3 do
177
        child.init_journal(User.find(2))
178
        child.project = Project.find(2)
179
        assert child.save
180
      end
181
    end
159 182
    child.reload
160 183
    grandchild.reload
161 184
    parent1.reload
......
173 196
    grandchild = child.generate_child!
174 197

  
175 198
    child.reload
176
    child.parent_issue_id = grandchild.id
177
    assert !child.save
199
    assert_no_difference 'Journal.count' do
200
      child.init_journal(User.find(2))
201
      child.parent_issue_id = grandchild.id
202
      assert !child.save
203
    end
178 204
    assert_not_equal [], child.errors[:parent_issue_id]
179 205
  end
180 206

  
......
223 249
    issue3.subject = 'child with journal'
224 250
    issue3.save!
225 251
    assert_difference 'Issue.count', -2 do
226
      assert_difference 'Journal.count', -1 do
227
        assert_difference 'JournalDetail.count', -1 do
252
      assert_difference 'Journal.count', -2 do
253
        assert_difference 'JournalDetail.count', -2 do
228 254
          Issue.find(issue2.id).destroy
229 255
        end
230 256
      end
......
244 270
    child2 = issue.generate_child!
245 271
    issue.reload
246 272
    assert_equal [issue.id, lft1, lft1 + 5], [issue.root_id, issue.lft, issue.rgt]
247
    child2.reload.destroy
273
    assert_difference 'Journal.count', 1 do
274
      child2.reload.destroy
275
    end
248 276
    issue.reload
249 277
    assert_equal [issue.id, lft1, lft1 + 3], [issue.root_id, issue.lft, issue.rgt]
250 278
  end
......
255 283
    parent.generate_child!(:start_date => 2.days.from_now)
256 284

  
257 285
    assert_difference 'Issue.count', -3 do
258
      Issue.find(parent.id).destroy
286
      assert_difference 'Journal.count', -2 do
287
        Issue.find(parent.id).destroy
288
      end
259 289
    end
260 290
  end
261 291

  
......
287 317
    grandchild1 = child.generate_child!
288 318
    grandchild2 = child.generate_child!
289 319
    assert_difference 'Issue.count', -4 do
290
      Issue.find(issue.id).destroy
320
      assert_difference 'Journal.count', -2 do
321
        Issue.find(issue.id).destroy
322
      end
291 323
      parent.reload
292 324
      assert_equal [lft1, lft1 + 1], [parent.lft, parent.rgt]
293 325
    end
test/unit/issue_subtasking_test.rb
277 277
    with_settings :issue_done_ratio => 'issue_status' do
278 278
      status = IssueStatus.find(4)
279 279
      status.update_attribute :default_done_ratio, 50
280
      child1.reload
280 281
      child1.update_attribute :status, status
281 282

  
282 283
      assert_equal 50, child1.done_ratio
test/unit/mail_handler_test.rb
433 433
    assert issue.is_a?(Issue)
434 434
    assert !issue.new_record?
435 435

  
436
    mail = ActionMailer::Base.deliveries.last
437
    assert_not_nil mail
438
    assert mail.subject.include?("##{issue.id}")
439
    assert mail.subject.include?('New ticket on a given project')
436
    assert_equal 4, issue.parent_issue_id
437
    assert_equal 2, ActionMailer::Base.deliveries.size
438

  
439
    [
440
      [issue.id, 'New ticket on a given project'],
441
      [4, 'Issue on project 2'],
442
    ].each do |issue_id, issue_subject|
443
      mail =
444
        ActionMailer::Base.deliveries.detect do |m|
445
          /##{issue_id}/.match?(m.subject) && /#{issue_subject}/.match?(m.subject)
446
        end
447
      assert_not_nil mail
448
    end
440 449
  end
441 450

  
442 451
  def test_created_user_should_be_added_to_groups
(3-3/3)