diff --git a/app/finders/groups/user_groups_finder.rb b/app/finders/groups/user_groups_finder.rb index 90367638dcf2ad1cede6c70185cc48e854c12269..c77599530dfa196a4ee3de764f8d429bdd5c1cc9 100644 --- a/app/finders/groups/user_groups_finder.rb +++ b/app/finders/groups/user_groups_finder.rb @@ -41,7 +41,7 @@ def sort(items) def by_search(items) return items if params[:search].blank? - items.search(params[:search]) + items.search(params[:search], include_parents: true) end def by_permission_scope diff --git a/spec/finders/groups/user_groups_finder_spec.rb b/spec/finders/groups/user_groups_finder_spec.rb index 9339741da79938c83f3b476f7883b526726d2a5c..999079468e59a46791ea7b14201086e593d80d23 100644 --- a/spec/finders/groups/user_groups_finder_spec.rb +++ b/spec/finders/groups/user_groups_finder_spec.rb @@ -5,17 +5,19 @@ RSpec.describe Groups::UserGroupsFinder do describe '#execute' do let_it_be(:user) { create(:user) } + let_it_be(:root_group) { create(:group, name: 'Root group', path: 'root-group') } let_it_be(:guest_group) { create(:group, name: 'public guest', path: 'public-guest') } - let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer') } - let_it_be(:public_developer_group) { create(:group, project_creation_level: nil, name: 'c public developer', path: 'c-public-developer') } - let_it_be(:public_maintainer_group) { create(:group, name: 'a public maintainer', path: 'a-public-maintainer') } + let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer', parent: root_group) } + let_it_be(:public_developer_group) { create(:group, project_creation_level: nil, name: 'c public developer', path: 'c-public-developer', parent: root_group) } + let_it_be(:public_maintainer_group) { create(:group, name: 'a public maintainer', path: 'a-public-maintainer', parent: root_group) } let_it_be(:public_owner_group) { create(:group, name: 'a public owner', path: 'a-public-owner') } - subject { described_class.new(current_user, target_user, arguments).execute } + subject { described_class.new(current_user, target_user, arguments.merge(search_arguments)).execute } let(:arguments) { {} } let(:current_user) { user } let(:target_user) { user } + let(:search_arguments) { {} } before_all do guest_group.add_guest(user) @@ -25,15 +27,40 @@ public_owner_group.add_owner(user) end - it 'returns all groups where the user is a direct member' do - is_expected.to match( - [ + shared_examples 'user group finder searching by name or path' do + let(:search_arguments) { { search: 'maintainer' } } + + specify do + is_expected.to contain_exactly( public_maintainer_group, - public_owner_group, - private_maintainer_group, - public_developer_group, - guest_group - ] + private_maintainer_group + ) + end + + context 'when searching for a full path (including parent)' do + let(:search_arguments) { { search: 'root-group/b-private-maintainer' } } + + specify do + is_expected.to contain_exactly(private_maintainer_group) + end + end + + context 'when search keywords include the parent route' do + let(:search_arguments) { { search: 'root public' } } + + specify do + is_expected.to match(keyword_search_expected_groups) + end + end + end + + it 'returns all groups where the user is a direct member' do + is_expected.to contain_exactly( + public_maintainer_group, + public_owner_group, + private_maintainer_group, + public_developer_group, + guest_group ) end @@ -53,26 +80,20 @@ let(:arguments) { { permission_scope: :create_projects } } specify do - is_expected.to match( + is_expected.to contain_exactly( + public_maintainer_group, + public_owner_group, + private_maintainer_group, + public_developer_group + ) + end + + it_behaves_like 'user group finder searching by name or path' do + let(:keyword_search_expected_groups) do [ public_maintainer_group, - public_owner_group, - private_maintainer_group, public_developer_group ] - ) - end - - context 'when search is provided' do - let(:arguments) { { permission_scope: :create_projects, search: 'maintainer' } } - - specify do - is_expected.to match( - [ - public_maintainer_group, - private_maintainer_group - ] - ) end end end @@ -81,38 +102,15 @@ let(:arguments) { { permission_scope: :transfer_projects } } specify do - is_expected.to match( - [ - public_maintainer_group, - public_owner_group, - private_maintainer_group - ] + is_expected.to contain_exactly( + public_maintainer_group, + public_owner_group, + private_maintainer_group ) end - context 'when search is provided' do - let(:arguments) { { permission_scope: :transfer_projects, search: 'owner' } } - - specify do - is_expected.to match( - [ - public_owner_group - ] - ) - end - end - end - - context 'when search is provided' do - let(:arguments) { { search: 'maintainer' } } - - specify do - is_expected.to match( - [ - public_maintainer_group, - private_maintainer_group - ] - ) + it_behaves_like 'user group finder searching by name or path' do + let(:keyword_search_expected_groups) { [public_maintainer_group] } end end end diff --git a/spec/requests/api/graphql/current_user/groups_query_spec.rb b/spec/requests/api/graphql/current_user/groups_query_spec.rb index ef0f32bacf08d6ed18f2a65a13dcf111891c4f94..6e36beb2afc7540d84286baaddeb65bd23a7d55a 100644 --- a/spec/requests/api/graphql/current_user/groups_query_spec.rb +++ b/spec/requests/api/graphql/current_user/groups_query_spec.rb @@ -6,10 +6,11 @@ include GraphqlHelpers let_it_be(:user) { create(:user) } + let_it_be(:root_group) { create(:group, name: 'Root group', path: 'root-group') } let_it_be(:guest_group) { create(:group, name: 'public guest', path: 'public-guest') } - let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer') } + let_it_be(:private_maintainer_group) { create(:group, :private, name: 'b private maintainer', path: 'b-private-maintainer', parent: root_group) } let_it_be(:public_developer_group) { create(:group, project_creation_level: nil, name: 'c public developer', path: 'c-public-developer') } - let_it_be(:public_maintainer_group) { create(:group, name: 'a public maintainer', path: 'a-public-maintainer') } + let_it_be(:public_maintainer_group) { create(:group, name: 'a public maintainer', path: 'a-public-maintainer', parent: root_group) } let_it_be(:public_owner_group) { create(:group, name: 'a public owner', path: 'a-public-owner') } let(:group_arguments) { {} } @@ -77,7 +78,7 @@ end context 'when search is provided' do - let(:group_arguments) { { permission_scope: :CREATE_PROJECTS, search: 'maintainer' } } + let(:group_arguments) { { permission_scope: :CREATE_PROJECTS, search: 'root-group maintainer' } } specify do is_expected.to match( @@ -127,6 +128,18 @@ ) ) end + + context 'when searching for a full path (including parent)' do + let(:group_arguments) { { search: 'root-group/b-private-maintainer' } } + + specify do + is_expected.to match( + expected_group_hash( + private_maintainer_group + ) + ) + end + end end def expected_group_hash(*groups)