Project

General

Profile

Feature #6033 » 6033_subtasks_show_in_parent_history.patch

Yuichi HARADA, 2019-08-16 04:19

View differences:

app/helpers/issues_helper.rb
426 426
        value = "##{detail.value}" unless detail.value.blank?
427 427
        old_value = "##{detail.old_value}" unless detail.old_value.blank?
428 428

  
429
      when 'child_id'
430
        label = l(:label_subtask)
431
        value = "##{detail.value}" unless detail.value.blank?
432
        old_value = "##{detail.old_value}" unless detail.old_value.blank?
433
        multiple = true
434

  
429 435
      when 'is_private'
430 436
        value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank?
431 437
        old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank?
app/models/issue.rb
114 114
  after_save :reschedule_following_issues, :update_nested_set_attributes,
115 115
             :update_parent_attributes, :delete_selected_attachments, :create_journal
116 116
  # Should be after_create but would be called before previous after_save callbacks
117
  after_save :after_create_from_copy
118
  after_destroy :update_parent_attributes
117
  after_save :after_create_from_copy, :create_parent_issue_journal
118
  after_destroy :update_parent_attributes, :create_parent_issue_journal
119 119
  after_create_commit :send_notification
120 120

  
121 121
  # Returns a SQL conditions string used to find all issues visible by the specified user
......
1845 1845
    end
1846 1846
  end
1847 1847

  
1848
  def create_parent_issue_journal
1849
    return if persisted? && !saved_change_to_parent_id?
1850
    return if destroyed? && @without_nested_set_update
1851

  
1852
    child_id = self.id
1853
    old_parent_id, new_parent_id =
1854
      if persisted?
1855
        [parent_id_before_last_save, parent_id]
1856
      elsif destroyed?
1857
        [parent_id, nil]
1858
      else
1859
        [nil, parent_id]
1860
      end
1861

  
1862
    if old_parent_id.present? && old_parent_issue = Issue.visible.find_by_id(old_parent_id)
1863
      old_parent_issue.init_journal(User.current)
1864
      old_parent_issue.current_journal.__send__(:add_attribute_detail, 'child_id', child_id, nil)
1865
      old_parent_issue.save
1866
    end
1867
    if new_parent_id.present? && new_parent_issue = Issue.visible.find_by_id(new_parent_id)
1868
      new_parent_issue.init_journal(User.current)
1869
      new_parent_issue.current_journal.__send__(:add_attribute_detail, 'child_id', nil, child_id)
1870
      new_parent_issue.save
1871
    end
1872
  end
1873

  
1848 1874
  def send_notification
1849 1875
    if notify? && Setting.notified_events.include?('issue_added')
1850 1876
      Mailer.deliver_issue_add(self)
config/locales/en.yml
950 950
  label_missing_api_access_key: Missing an API access key
951 951
  label_api_access_key_created_on: "API access key created %{value} ago"
952 952
  label_profile: Profile
953
  label_subtask: Subtask
953 954
  label_subtask_plural: Subtasks
954 955
  label_project_copy_notifications: Send email notifications during the project copy
955 956
  label_import_notifications: Send email notifications during the import
test/functional/issues_controller_test.rb
1956 1956
  end
1957 1957

  
1958 1958
  def test_show_should_list_subtasks
1959
    Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1959
    issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1960 1960

  
1961 1961
    get :show, :params => {
1962 1962
        :id => 1
......
1966 1966
    assert_select 'div#issue_tree' do
1967 1967
      assert_select 'td.subject', :text => /Child Issue/
1968 1968
    end
1969
    assert_select 'div#tab-content-history' do
1970
      assert_select 'div[id=?]', "change-#{Issue.find(1).journals.last.id}" do
1971
        assert_select 'ul.details', :text => "Subtask ##{issue.id} added"
1972
      end
1973
    end
1969 1974
  end
1970 1975

  
1971 1976
  def test_show_should_list_parents
......
6866 6871
    assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
6867 6872
  end
6868 6873

  
6874
  def test_destroy_child_issue
6875
    parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
6876
    child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
6877
    assert child.is_descendant_of?(parent.reload)
6878

  
6879
    @request.session[:user_id] = 2
6880
    assert_difference 'Issue.count', -1 do
6881
      delete :destroy, :params => {
6882
          :id => child.id
6883
        }
6884
    end
6885
    assert_response :found
6886
    assert_redirected_to :action => 'index', :project_id => 'ecookbook'
6887

  
6888
    parent.reload
6889
    assert_equal 2, parent.journals.count
6890

  
6891
    get :show, :params => {
6892
        :id => parent.id
6893
      }
6894
    assert_response :success
6895

  
6896
    assert_select 'div#tab-content-history' do
6897
      assert_select 'div[id=?]', "change-#{parent.journals.last.id}" do
6898
        assert_select 'ul.details', :text => "Subtask deleted (##{child.id})"
6899
      end
6900
    end
6901
  end
6902

  
6869 6903
  def test_destroy_parent_and_child_issues
6870 6904
    parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
6871 6905
    child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
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
267 267
    with_settings :issue_done_ratio => 'issue_status' do
268 268
      status = IssueStatus.find(4)
269 269
      status.update_attribute :default_done_ratio, 50
270
      child1.reload
270 271
      child1.update_attribute :status, status
271 272

  
272 273
      assert_equal 50, child1.done_ratio
test/unit/issue_test.rb
1381 1381
    copy = issue.reload.copy
1382 1382
    assert_difference 'Issue.count', 1+issue.descendants.count do
1383 1383
      assert copy.save
1384
      copy.reload
1384 1385
      assert copy.save
1385 1386
    end
1386 1387
  end
(1-1/3)