Commit 8f6dac49 authored by Bob Van Landuyt's avatar Bob Van Landuyt

Allow filtering children for a group

When fetching children for a group with a filter, we will search all
nested groups for results and render them in an expanded tree
parent 518216c0
...@@ -74,11 +74,11 @@ class GroupsController < Groups::ApplicationController ...@@ -74,11 +74,11 @@ class GroupsController < Groups::ApplicationController
respond_to do |format| respond_to do |format|
format.json do format.json do
render json: GroupChildSerializer serializer = GroupChildSerializer
.new(current_user: current_user) .new(current_user: current_user)
.with_pagination(request, response) .with_pagination(request, response)
.hierarchy_base(parent, open_hierarchy: filter[:filter].present) serializer.expand_hierarchy(parent) if params[:filter].present?
.represent(@children) render json: serializer.represent(@children)
end end
end end
end end
......
...@@ -18,11 +18,14 @@ class GroupChildSerializer < BaseSerializer ...@@ -18,11 +18,14 @@ class GroupChildSerializer < BaseSerializer
end end
end end
protected
def represent_hierarchies(children, opts) def represent_hierarchies(children, opts)
if children.is_a?(GroupHierarchy) if children.is_a?(GroupHierarchy)
represent_hierarchy(children.hierarchy(hierarchy_root), opts) represent_hierarchy(children.hierarchy(hierarchy_root), opts).first
else else
children.map { |child| represent_hierarchy(child.hierarchy(hierarchy_root), opts) } hierarchies = Array.wrap(GroupHierarchy.merge_hierarchies(children, hierarchy_root))
hierarchies.map { |hierarchy| represent_hierarchy(hierarchy, opts) }.flatten
end end
end end
...@@ -30,9 +33,10 @@ class GroupChildSerializer < BaseSerializer ...@@ -30,9 +33,10 @@ class GroupChildSerializer < BaseSerializer
serializer = self.class.new(parameters) serializer = self.class.new(parameters)
result = if hierarchy.is_a?(Hash) result = if hierarchy.is_a?(Hash)
parent = hierarchy.keys.first hierarchy.map do |parent, children|
serializer.represent(parent, opts) serializer.represent(parent, opts)
.merge(children: [serializer.represent_hierarchy(hierarchy[parent], opts)]) .merge(children: Array.wrap(serializer.represent_hierarchy(children, opts)))
end
else else
serializer.represent(hierarchy, opts) serializer.represent(hierarchy, opts)
end end
......
...@@ -224,6 +224,36 @@ describe GroupsController do ...@@ -224,6 +224,36 @@ describe GroupsController do
expect(assigns(:children)).to contain_exactly(public_subgroup, public_project) expect(assigns(:children)).to contain_exactly(public_subgroup, public_project)
end end
end end
context 'filtering children' do
def get_filtered_list
get :children, id: group.to_param, filter: 'filter', format: :json
end
it 'expands the tree for matching projects' do
project = create(:project, :public, namespace: public_subgroup, name: 'filterme')
get_filtered_list
group_json = json_response.first
project_json = group_json['children'].first
expect(group_json['id']).to eq(public_subgroup.id)
expect(project_json['id']).to eq(project.id)
end
it 'expands the tree for matching subgroups' do
matched_group = create(:group, :public, parent: public_subgroup, name: 'filterme')
get_filtered_list
group_json = json_response.first
matched_group_json = group_json['children'].first
expect(group_json['id']).to eq(public_subgroup.id)
expect(matched_group_json['id']).to eq(matched_group.id)
end
end
end end
end end
......
...@@ -16,7 +16,7 @@ describe GroupChildSerializer do ...@@ -16,7 +16,7 @@ describe GroupChildSerializer do
end end
end end
context 'with a hierarchy' do context 'with a hierarchy', :nested_groups do
let(:parent) { create(:group) } let(:parent) { create(:group) }
subject(:serializer) do subject(:serializer) do
...@@ -35,8 +35,51 @@ describe GroupChildSerializer do ...@@ -35,8 +35,51 @@ describe GroupChildSerializer do
expect(subsub_group_json[:id]).to eq(subsub_group.id) expect(subsub_group_json[:id]).to eq(subsub_group.id)
end end
it 'can expand multiple trees' do it 'can render a nested tree' do
subgroup1 = create(:group, parent: parent)
subsub_group1 = create(:group, parent: subgroup1)
subgroup2 = create(:group, parent: parent)
subsub_group2 = create(:group, parent: subgroup2)
json = serializer.represent([subsub_group1, subsub_group2])
subgroup1_json = json.first
subsub_group1_json = subgroup1_json[:children].first
expect(json.size).to eq(2)
expect(subgroup1_json[:id]).to eq(subgroup1.id)
expect(subsub_group1_json[:id]).to eq(subsub_group1.id)
end
end
context 'for projects' do
it 'can render a single project' do
expect(serializer.represent(build(:project))).to be_kind_of(Hash)
end
it 'can render a collection of projects' do
expect(serializer.represent(build_list(:project, 2))).to be_kind_of(Array)
end
context 'with a hierarchy', :nested_groups do
let(:parent) { create(:group) }
subject(:serializer) do
described_class.new(current_user: user).expand_hierarchy(parent)
end
it 'can render a nested tree' do
subgroup1 = create(:group, parent: parent)
project1 = create(:project, namespace: subgroup1)
subgroup2 = create(:group, parent: parent)
project2 = create(:project, namespace: subgroup2)
json = serializer.represent([project1, project2])
project1_json, project2_json = json.map { |group_json| group_json[:children].first }
expect(json.size).to eq(2)
expect(project1_json[:id]).to eq(project1.id)
expect(project2_json[:id]).to eq(project2.id)
end
end end
end end
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