Commit 6d906d28 authored by Felipe Artur's avatar Felipe Artur

Increase epic max child hierarchy to seven

Increase the number of epics users can
nest under a parent epic from 5 to 7
parent 56b6f594
...@@ -96,7 +96,7 @@ New child epics appear at the top of the list of epics in the **Epics and Issues ...@@ -96,7 +96,7 @@ New child epics appear at the top of the list of epics in the **Epics and Issues
When you add an epic that's already linked to a parent epic, the link to its current parent is removed. When you add an epic that's already linked to a parent epic, the link to its current parent is removed.
An epic can have multiple child epics up to the maximum depth of five. An epic can have multiple child epics up to the maximum depth of seven.
See [Manage multi-level child epics](manage_epics.md#manage-multi-level-child-epics) for See [Manage multi-level child epics](manage_epics.md#manage-multi-level-child-epics) for
steps to create, move, reorder, or delete child epics. steps to create, move, reorder, or delete child epics.
......
...@@ -119,7 +119,7 @@ module EE ...@@ -119,7 +119,7 @@ module EE
public_only.or(where(confidential: true, group_id: groups)) public_only.or(where(confidential: true, group_id: groups))
end end
MAX_HIERARCHY_DEPTH = 5 MAX_HIERARCHY_DEPTH = 7
def etag_caching_enabled? def etag_caching_enabled?
true true
......
---
title: Increase the Epic Nesting from 5 to 7
merge_request: 49619
author:
type: changed
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'Epic Issues', :js do RSpec.describe 'Epic Issues', :js do
include NestedEpicsHelper
include DragTo include DragTo
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -195,13 +196,9 @@ RSpec.describe 'Epic Issues', :js do ...@@ -195,13 +196,9 @@ RSpec.describe 'Epic Issues', :js do
end end
context 'when epics are nested too deep' do context 'when epics are nested too deep' do
let(:epic1) { create(:epic, group: group, parent_id: epic.id) }
let(:epic2) { create(:epic, group: group, parent_id: epic1.id) }
let(:epic3) { create(:epic, group: group, parent_id: epic2.id) }
let(:epic4) { create(:epic, group: group, parent_id: epic3.id) }
before do before do
visit group_epic_path(group, epic4) last_child = add_children_to(epic: epic, count: 6)
visit group_epic_path(group, last_child)
wait_for_requests wait_for_requests
...@@ -215,7 +212,7 @@ RSpec.describe 'Epic Issues', :js do ...@@ -215,7 +212,7 @@ RSpec.describe 'Epic Issues', :js do
add_epics(references) add_epics(references)
expect(page).to have_selector('.gl-field-error') expect(page).to have_selector('.gl-field-error')
expect(find('.gl-field-error')).to have_text("This epic cannot be added. One or more epics would exceed the maximum depth (5) from its most distant ancestor.") expect(find('.gl-field-error')).to have_text("This epic cannot be added. One or more epics would exceed the maximum depth (#{Epic::MAX_HIERARCHY_DEPTH}) from its most distant ancestor.")
end end
end end
end end
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Epic do RSpec.describe Epic do
include NestedEpicsHelper
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let(:project) { create(:project, group: group) } let(:project) { create(:project, group: group) }
...@@ -185,31 +187,28 @@ RSpec.describe Epic do ...@@ -185,31 +187,28 @@ RSpec.describe Epic do
it 'returns false when level is too deep' do it 'returns false when level is too deep' do
epic1 = create(:epic, group: group) epic1 = create(:epic, group: group)
epic2 = create(:epic, group: group, parent: epic1) add_parents_to(epic: epic1, count: 6)
epic3 = create(:epic, group: group, parent: epic2)
epic4 = create(:epic, group: group, parent: epic3) epic.parent = epic1
epic5 = create(:epic, group: group, parent: epic4)
epic.parent = epic5
expect(epic.valid_parent?).to be_falsey expect(epic.valid_parent?).to be_falsey
end end
end end
context 'when adding an Epic that has existing children' do context 'when adding an Epic that has existing children' do
let(:parent_epic) { create(:epic, group: group) } let_it_be(:parent_epic) { create(:epic, group: group) }
let(:epic) { build(:epic, group: group) } let(:epic) { build(:epic, group: group) }
let(:child_epic1) { create(:epic, group: group, parent: epic)}
it 'returns true when total depth after adding will not exceed limit' do it 'returns true when total depth after adding will not exceed limit' do
create(:epic, group: group, parent: epic)
epic.parent = parent_epic epic.parent = parent_epic
expect(epic.valid_parent?).to be_truthy expect(epic.valid_parent?).to be_truthy
end end
it 'returns false when total depth after adding would exceed limit' do it 'returns false when total depth after adding would exceed limit' do
child_epic2 = create(:epic, group: group, parent: child_epic1) add_children_to(epic: epic, count: 6)
child_epic3 = create(:epic, group: group, parent: child_epic2)
create(:epic, group: group, parent: child_epic3)
epic.parent = parent_epic epic.parent = parent_epic
...@@ -218,8 +217,8 @@ RSpec.describe Epic do ...@@ -218,8 +217,8 @@ RSpec.describe Epic do
end end
context 'when parent has ancestors and epic has children' do context 'when parent has ancestors and epic has children' do
let(:root_epic) { create(:epic, group: group) } let_it_be(:root_epic) { create(:epic, group: group) }
let(:parent_epic) { create(:epic, group: group, parent: root_epic) } let_it_be(:parent_epic) { create(:epic, group: group, parent: root_epic) }
let(:epic) { build(:epic, group: group) } let(:epic) { build(:epic, group: group) }
let(:child_epic1) { create(:epic, group: group, parent: epic)} let(:child_epic1) { create(:epic, group: group, parent: epic)}
...@@ -230,8 +229,8 @@ RSpec.describe Epic do ...@@ -230,8 +229,8 @@ RSpec.describe Epic do
end end
it 'returns false when total depth after adding would exceed limit' do it 'returns false when total depth after adding would exceed limit' do
root_epic.update(parent: create(:epic, group: group)) add_parents_to(epic: root_epic, count: 2)
create(:epic, group: group, parent: child_epic1) add_children_to(epic: child_epic1, count: 2)
epic.parent = parent_epic epic.parent = parent_epic
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe EpicLinks::CreateService do RSpec.describe EpicLinks::CreateService do
include NestedEpicsHelper
describe '#execute' do describe '#execute' do
let(:group) { create(:group) } let(:group) { create(:group) }
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -148,34 +150,25 @@ RSpec.describe EpicLinks::CreateService do ...@@ -148,34 +150,25 @@ RSpec.describe EpicLinks::CreateService do
context 'when adding to an Epic that is already at maximum depth' do context 'when adding to an Epic that is already at maximum depth' do
before do before do
epic1 = create(:epic, group: group) add_parents_to(epic: epic, count: 6)
epic2 = create(:epic, group: group, parent: epic1)
epic3 = create(:epic, group: group, parent: epic2)
epic4 = create(:epic, group: group, parent: epic3)
epic.update(parent: epic4)
end end
let(:expected_error) { "This epic cannot be added. One or more epics would exceed the maximum depth (5) from its most distant ancestor." } let(:expected_error) { "This epic cannot be added. One or more epics would exceed the maximum depth (#{Epic::MAX_HIERARCHY_DEPTH}) from its most distant ancestor." }
let(:expected_code) { 409 } let(:expected_code) { 409 }
include_examples 'returns an error' include_examples 'returns an error'
end end
context 'when total depth after adding would exceed depth limit' do context 'when total depth after adding would exceed depth limit' do
let(:expected_error) { "This epic cannot be added. One or more epics would exceed the maximum depth (5) from its most distant ancestor." } let(:expected_error) { "This epic cannot be added. One or more epics would exceed the maximum depth (#{Epic::MAX_HIERARCHY_DEPTH}) from its most distant ancestor." }
let(:expected_code) { 409 } let(:expected_code) { 409 }
before do before do
epic1 = create(:epic, group: group) add_parents_to(epic: epic, count: 1) # epic is on level 2
epic.update(parent: epic1) # epic is on level 2 # epic_to_add has 5 children (level 6 including epic_to_add)
# that would mean level 8 after relating epic_to_add on epic
# epic_to_add has 3 children (level 4 including epic_to_add) add_children_to(epic: epic_to_add, count: 5)
# that would mean level 6 after relating epic_to_add on epic
epic2 = create(:epic, group: group, parent: epic_to_add)
epic3 = create(:epic, group: group, parent: epic2)
create(:epic, group: group, parent: epic3)
end end
include_examples 'returns an error' include_examples 'returns an error'
...@@ -215,15 +208,11 @@ RSpec.describe EpicLinks::CreateService do ...@@ -215,15 +208,11 @@ RSpec.describe EpicLinks::CreateService do
context 'when total depth after adding would exceed limit' do context 'when total depth after adding would exceed limit' do
before do before do
epic1 = create(:epic, group: group) add_parents_to(epic: epic, count: 1) # epic is on level 2
epic.update(parent: epic1) # epic is on level 2
# epic_to_add has 3 children (level 4 including epic_to_add) # epic_to_add has 5 children (level 6 including epic_to_add)
# that would mean level 6 after relating epic_to_add on epic # that would mean level 8 after relating epic_to_add on epic
epic2 = create(:epic, group: group, parent: epic_to_add) add_children_to(epic: epic_to_add, count: 5)
epic3 = create(:epic, group: group, parent: epic2)
create(:epic, group: group, parent: epic3)
end end
let(:another_epic) { create(:epic) } let(:another_epic) { create(:epic) }
......
# frozen_string_literal: true
module NestedEpicsHelper
def add_parents_to(epic:, count:)
latest = nil
count.times do
latest = create(:epic, group: epic.group, parent: latest)
end
epic.update!(parent: latest)
latest
end
def add_children_to(epic:, count:)
latest = epic
count.times do
latest = create(:epic, group: epic.group, parent: latest)
end
latest
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment