Commit 674a5686 authored by Brett Walker's avatar Brett Walker Committed by Markus Koller

Support include_ancestors to group milestone query

for the GraphQL query
parent 0565b69f
......@@ -5,18 +5,37 @@ module Resolvers
class GroupMilestonesResolver < MilestonesResolver
argument :include_descendants, GraphQL::BOOLEAN_TYPE,
required: false,
description: 'Also return milestones in all subgroups and subprojects.'
description: 'Include milestones from all subgroups and subprojects.'
argument :include_ancestors, GraphQL::BOOLEAN_TYPE,
required: false,
description: 'Include milestones from all parent groups.'
type Types::MilestoneType.connection_type, null: true
private
def parent_id_parameters(args)
return { group_ids: parent.id } unless args[:include_descendants].present?
include_ancestors = args[:include_ancestors].present?
include_descendants = args[:include_descendants].present?
return { group_ids: parent.id } unless include_ancestors || include_descendants
group_ids = if include_ancestors && include_descendants
parent.self_and_hierarchy
elsif include_ancestors
parent.self_and_ancestors
else
parent.self_and_descendants
end
project_ids = if include_descendants
group_projects.with_issues_or_mrs_available_for_user(current_user)
else
nil
end
{
group_ids: parent.self_and_descendants.public_or_visible_to_user(current_user).select(:id),
project_ids: group_projects.with_issues_or_mrs_available_for_user(current_user)
group_ids: group_ids.public_or_visible_to_user(current_user).select(:id),
project_ids: project_ids
}
end
......
---
title: Support include_ancestors when querying group milestones via GraphQL
merge_request: 56667
author:
type: added
......@@ -136,5 +136,56 @@ RSpec.describe Resolvers::GroupMilestonesResolver do
expect(resolve_group_milestones(args)).to match_array([milestone1, milestone2, milestone3])
end
end
describe 'include_descendants and include_ancestors' do
let_it_be(:parent_group) { create(:group, :public) }
let_it_be(:group) { create(:group, :public, parent: parent_group) }
let_it_be(:accessible_group) { create(:group, :private, parent: group) }
let_it_be(:accessible_project) { create(:project, group: accessible_group) }
let_it_be(:inaccessible_group) { create(:group, :private, parent: group) }
let_it_be(:inaccessible_project) { create(:project, :private, group: group) }
let_it_be(:milestone1) { create(:milestone, group: group) }
let_it_be(:milestone2) { create(:milestone, group: accessible_group) }
let_it_be(:milestone3) { create(:milestone, project: accessible_project) }
let_it_be(:milestone4) { create(:milestone, group: inaccessible_group) }
let_it_be(:milestone5) { create(:milestone, project: inaccessible_project) }
let_it_be(:milestone6) { create(:milestone, group: parent_group) }
before do
accessible_group.add_developer(current_user)
end
context 'when including neither ancestor or descendant milestones in a public group' do
let(:args) { {} }
it 'finds milestones only in accessible projects and groups' do
expect(resolve_group_milestones(args)).to match_array([milestone1])
end
end
context 'when including descendant milestones in a public group' do
let(:args) { { include_descendants: true } }
it 'finds milestones only in accessible projects and groups' do
expect(resolve_group_milestones(args)).to match_array([milestone1, milestone2, milestone3])
end
end
context 'when including ancestor milestones in a public group' do
let(:args) { { include_ancestors: true } }
it 'finds milestones only in accessible projects and groups' do
expect(resolve_group_milestones(args)).to match_array([milestone1, milestone6])
end
end
context 'when including both ancestor or descendant milestones in a public group' do
let(:args) { { include_descendants: true, include_ancestors: true } }
it 'finds milestones only in accessible projects and groups' do
expect(resolve_group_milestones(args)).to match_array([milestone1, milestone2, milestone3, milestone6])
end
end
end
end
end
......@@ -9,12 +9,14 @@ RSpec.describe 'Milestones through GroupQuery' do
let_it_be(:now) { Time.now }
describe 'Get list of milestones from a group' do
let_it_be(:group) { create(:group) }
let_it_be(:parent_group) { create(:group) }
let_it_be(:group) { create(:group, parent: parent_group) }
let_it_be(:milestone_1) { create(:milestone, group: group) }
let_it_be(:milestone_2) { create(:milestone, group: group, state: :closed, start_date: now, due_date: now + 1.day) }
let_it_be(:milestone_3) { create(:milestone, group: group, start_date: now, due_date: now + 2.days) }
let_it_be(:milestone_4) { create(:milestone, group: group, state: :closed, start_date: now - 2.days, due_date: now - 1.day) }
let_it_be(:milestone_from_other_group) { create(:milestone, group: create(:group)) }
let_it_be(:parent_milestone) { create(:milestone, group: parent_group) }
let(:milestone_data) { graphql_data['group']['milestones']['edges'] }
......@@ -64,14 +66,32 @@ RSpec.describe 'Milestones through GroupQuery' do
accessible_group.add_developer(user)
end
it 'returns milestones also from subgroups and subprojects visible to user' do
fetch_milestones(user, args)
context 'when including decendants' do
let(:args) { { include_descendants: true } }
it 'returns milestones also from subgroups and subprojects visible to user' do
fetch_milestones(user, args)
expect_array_response(
milestone_1.to_global_id.to_s, milestone_2.to_global_id.to_s,
milestone_3.to_global_id.to_s, milestone_4.to_global_id.to_s,
submilestone_1.to_global_id.to_s, submilestone_2.to_global_id.to_s
)
end
end
context 'when including ancestors' do
let(:args) { { include_ancestors: true } }
expect_array_response(
milestone_1.to_global_id.to_s, milestone_2.to_global_id.to_s,
milestone_3.to_global_id.to_s, milestone_4.to_global_id.to_s,
submilestone_1.to_global_id.to_s, submilestone_2.to_global_id.to_s
)
it 'returns milestones from ancestor groups' do
fetch_milestones(user, args)
expect_array_response(
milestone_1.to_global_id.to_s, milestone_2.to_global_id.to_s,
milestone_3.to_global_id.to_s, milestone_4.to_global_id.to_s,
parent_milestone.to_global_id.to_s
)
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