Commit da759b75 authored by Dylan Griffith's avatar Dylan Griffith

Merge branch '332820-epics-from-all-parent-groups-should-be-fetched-in-issue-sidebar' into 'master'

Add 'include_ancestor_groups' argument to epics query

See merge request gitlab-org/gitlab!63374
parents 7719d2d2 87062904
...@@ -7229,6 +7229,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ...@@ -7229,6 +7229,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="boardepicchildreniid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". | | <a id="boardepicchildreniid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="boardepicchildreniidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. | | <a id="boardepicchildreniidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="boardepicchildreniids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. | | <a id="boardepicchildreniids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="boardepicchildrenincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="boardepicchildrenincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. | | <a id="boardepicchildrenincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="boardepicchildrenlabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. | | <a id="boardepicchildrenlabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="boardepicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="boardepicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
...@@ -8418,6 +8419,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ...@@ -8418,6 +8419,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="epicchildreniid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". | | <a id="epicchildreniid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="epicchildreniidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. | | <a id="epicchildreniidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="epicchildreniids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. | | <a id="epicchildreniids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="epicchildrenincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="epicchildrenincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. | | <a id="epicchildrenincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="epicchildrenlabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. | | <a id="epicchildrenlabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="epicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="epicchildrenmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
...@@ -9020,6 +9022,7 @@ Returns [`Epic`](#epic). ...@@ -9020,6 +9022,7 @@ Returns [`Epic`](#epic).
| <a id="groupepiciid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". | | <a id="groupepiciid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="groupepiciidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. | | <a id="groupepiciidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="groupepiciids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. | | <a id="groupepiciids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="groupepicincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="groupepicincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. | | <a id="groupepicincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="groupepiclabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. | | <a id="groupepiclabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="groupepicmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="groupepicmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
...@@ -9063,6 +9066,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ...@@ -9063,6 +9066,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupepicsiid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". | | <a id="groupepicsiid"></a>`iid` | [`ID`](#id) | IID of the epic, e.g., "1". |
| <a id="groupepicsiidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. | | <a id="groupepicsiidstartswith"></a>`iidStartsWith` | [`String`](#string) | Filter epics by IID for autocomplete. |
| <a id="groupepicsiids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. | | <a id="groupepicsiids"></a>`iids` | [`[ID!]`](#id) | List of IIDs of epics, e.g., [1, 2]. |
| <a id="groupepicsincludeancestorgroups"></a>`includeAncestorGroups` | [`Boolean`](#boolean) | Include epics from ancestor groups. |
| <a id="groupepicsincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. | | <a id="groupepicsincludedescendantgroups"></a>`includeDescendantGroups` | [`Boolean`](#boolean) | Include epics from descendant groups. |
| <a id="groupepicslabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. | | <a id="groupepicslabelname"></a>`labelName` | [`[String!]`](#string) | Filter epics by labels. |
| <a id="groupepicsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. | | <a id="groupepicsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Filter epics by milestone title, computed from epic's issues. |
......
...@@ -41,6 +41,11 @@ module Resolvers ...@@ -41,6 +41,11 @@ module Resolvers
required: false, required: false,
description: 'Filter epics by IID for autocomplete.' description: 'Filter epics by IID for autocomplete.'
argument :include_ancestor_groups, GraphQL::BOOLEAN_TYPE,
required: false,
description: 'Include epics from ancestor groups.',
default_value: false
argument :include_descendant_groups, GraphQL::BOOLEAN_TYPE, argument :include_descendant_groups, GraphQL::BOOLEAN_TYPE,
required: false, required: false,
description: 'Include epics from descendant groups.', description: 'Include epics from descendant groups.',
......
...@@ -140,10 +140,15 @@ RSpec.describe EpicsFinder do ...@@ -140,10 +140,15 @@ RSpec.describe EpicsFinder do
context 'when subgroups are supported' do context 'when subgroups are supported' do
let_it_be(:subgroup) { create(:group, :private, parent: group) } let_it_be(:subgroup) { create(:group, :private, parent: group) }
let_it_be(:subgroup_guest) { create(:user) }
let_it_be(:subgroup2) { create(:group, :private, parent: subgroup) } let_it_be(:subgroup2) { create(:group, :private, parent: subgroup) }
let_it_be(:subgroup_epic) { create(:epic, group: subgroup) } let_it_be(:subgroup_epic) { create(:epic, group: subgroup) }
let_it_be(:subgroup2_epic) { create(:epic, group: subgroup2) } let_it_be(:subgroup2_epic) { create(:epic, group: subgroup2) }
before do
subgroup.add_guest(subgroup_guest)
end
it 'returns all epics that belong to the given group and its subgroups' do it 'returns all epics that belong to the given group and its subgroups' do
expect(epics).to contain_exactly(epic1, epic2, epic3, subgroup_epic, subgroup2_epic) expect(epics).to contain_exactly(epic1, epic2, epic3, subgroup_epic, subgroup2_epic)
end end
...@@ -168,20 +173,36 @@ RSpec.describe EpicsFinder do ...@@ -168,20 +173,36 @@ RSpec.describe EpicsFinder do
let(:finder_params) { { include_descendant_groups: false, include_ancestor_groups: true } } let(:finder_params) { { include_descendant_groups: false, include_ancestor_groups: true } }
it { is_expected.to contain_exactly(subgroup_epic, epic1, epic2, epic3) } it { is_expected.to contain_exactly(subgroup_epic, epic1, epic2, epic3) }
context "when user does not have permission to view ancestor groups" do
let(:finder_params) { { group_id: subgroup.id, include_descendant_groups: false, include_ancestor_groups: true } }
subject { described_class.new(subgroup_guest, finder_params).execute }
it { is_expected.to contain_exactly(subgroup_epic) }
end
end end
end end
context 'when include_descendant_groups is true' do context 'when include_descendant_groups is true (by default)' do
context 'and include_ancestor_groups is false' do context 'and include_ancestor_groups is false' do
let(:finder_params) { { include_descendant_groups: true, include_ancestor_groups: false } } let(:finder_params) { { include_ancestor_groups: false } }
it { is_expected.to contain_exactly(subgroup_epic, subgroup2_epic) } it { is_expected.to contain_exactly(subgroup_epic, subgroup2_epic) }
end end
context 'and include_ancestor_groups is true' do context 'and include_ancestor_groups is true' do
let(:finder_params) { { include_descendant_groups: true, include_ancestor_groups: true } } let(:finder_params) { { include_ancestor_groups: true } }
it { is_expected.to contain_exactly(subgroup_epic, subgroup2_epic, epic1, epic2, epic3) } it { is_expected.to contain_exactly(subgroup_epic, subgroup2_epic, epic1, epic2, epic3) }
context "when user does not have permission to view ancestor groups" do
let(:finder_params) { { group_id: subgroup.id, include_ancestor_groups: true } }
subject { described_class.new(subgroup_guest, finder_params).execute }
it { is_expected.to contain_exactly(subgroup_epic, subgroup2_epic) }
end
end end
end end
......
...@@ -236,6 +236,16 @@ RSpec.describe Resolvers::EpicsResolver do ...@@ -236,6 +236,16 @@ RSpec.describe Resolvers::EpicsResolver do
expect(resolve_epics(milestone_title: milestone.title)).to contain_exactly(epic1, epic3) expect(resolve_epics(milestone_title: milestone.title)).to contain_exactly(epic1, epic3)
end end
context 'when the resolved group is a subgroup' do
it 'returns only the epics belonging to the subgroup by default' do
expect(resolve_epics({}, sub_group)).to contain_exactly(epic3, epic4)
end
it 'returns the epics belonging to the ancestor groups when include_ancestor_groups is true' do
expect(resolve_epics({ include_ancestor_groups: true }, sub_group)).to contain_exactly(epic1, epic2, epic3, epic4)
end
end
end end
context 'with partial iids' do context 'with partial iids' do
...@@ -315,7 +325,7 @@ RSpec.describe Resolvers::EpicsResolver do ...@@ -315,7 +325,7 @@ RSpec.describe Resolvers::EpicsResolver do
end end
end end
def resolve_epics(args = {}, context = { current_user: current_user }) def resolve_epics(args = {}, obj = group, context = { current_user: current_user })
resolve(described_class, obj: group, args: args, ctx: context) resolve(described_class, obj: obj, args: args, ctx: context)
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