Add a concern to build hierarchies of groups
This commit is contained in:
parent
9f3995a0ca
commit
438a0773dc
4 changed files with 90 additions and 0 deletions
27
app/models/concerns/group_hierarchy.rb
Normal file
27
app/models/concerns/group_hierarchy.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
module GroupHierarchy
|
||||
def hierarchy(hierarchy_base = nil)
|
||||
@hierarchy ||= tree_for_child(self, self, hierarchy_base)
|
||||
end
|
||||
|
||||
def parent
|
||||
if self.is_a?(Project)
|
||||
namespace
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def tree_for_child(child, tree, hierarchy_base)
|
||||
if child.parent.nil? && hierarchy_base.present?
|
||||
raise ArgumentError.new('specified base is not part of the tree')
|
||||
end
|
||||
|
||||
if child.parent != hierarchy_base
|
||||
tree_for_child(child.parent,
|
||||
{ child.parent => tree },
|
||||
hierarchy_base)
|
||||
else
|
||||
tree
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,6 +6,7 @@ class Group < Namespace
|
|||
include Avatarable
|
||||
include Referable
|
||||
include SelectForProjectAuthorization
|
||||
include GroupHierarchy
|
||||
|
||||
has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent
|
||||
alias_method :members, :group_members
|
||||
|
|
|
@ -17,6 +17,7 @@ class Project < ActiveRecord::Base
|
|||
include ProjectFeaturesCompatibility
|
||||
include SelectForProjectAuthorization
|
||||
include Routable
|
||||
include GroupHierarchy
|
||||
|
||||
extend Gitlab::ConfigHelper
|
||||
extend Gitlab::CurrentSettings
|
||||
|
|
61
spec/models/concerns/group_hierarchy_spec.rb
Normal file
61
spec/models/concerns/group_hierarchy_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe GroupHierarchy, :nested_groups do
|
||||
let(:parent) { create(:group) }
|
||||
let(:subgroup) { create(:group, parent: parent) }
|
||||
let(:subsub_group) { create(:group, parent: subgroup) }
|
||||
|
||||
context 'for a group' do
|
||||
describe '#hierarchy' do
|
||||
it 'builds a hierarchy for a group' do
|
||||
expected_hierarchy = { parent => { subgroup => subsub_group } }
|
||||
|
||||
expect(subsub_group.hierarchy).to eq(expected_hierarchy)
|
||||
end
|
||||
|
||||
it 'builds a hierarchy upto a specified parent' do
|
||||
expected_hierarchy = { subgroup => subsub_group }
|
||||
|
||||
expect(subsub_group.hierarchy(parent)).to eq(expected_hierarchy)
|
||||
end
|
||||
|
||||
it 'raises an error if specifying a base that is not part of the tree' do
|
||||
expect { subsub_group.hierarchy(double) }.to raise_error('specified base is not part of the tree')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#parent' do
|
||||
it 'returns the correct parent' do
|
||||
expect(subsub_group.parent).to eq(subgroup)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'for a project' do
|
||||
let(:project) { create(:project, namespace: subsub_group) }
|
||||
|
||||
describe '#hierarchy' do
|
||||
it 'builds a hierarchy for a group' do
|
||||
expected_hierarchy = { parent => { subgroup => { subsub_group => project } } }
|
||||
|
||||
expect(project.hierarchy).to eq(expected_hierarchy)
|
||||
end
|
||||
|
||||
it 'builds a hierarchy upto a specified parent' do
|
||||
expected_hierarchy = { subsub_group => project }
|
||||
|
||||
expect(project.hierarchy(subgroup)).to eq(expected_hierarchy)
|
||||
end
|
||||
|
||||
it 'raises an error if specifying a base that is not part of the tree' do
|
||||
expect { project.hierarchy(double) }.to raise_error('specified base is not part of the tree')
|
||||
end
|
||||
end
|
||||
|
||||
describe '#parent' do
|
||||
it 'returns the correct parent' do
|
||||
expect(project.parent).to eq(subsub_group)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue