diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
commit | b76ae638462ab0f673e5915986070518dd3f9ad3 (patch) | |
tree | bdab0533383b52873be0ec0eb4d3c66598ff8b91 /spec/finders | |
parent | 434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff) |
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'spec/finders')
-rw-r--r-- | spec/finders/ci/pipelines_finder_spec.rb | 23 | ||||
-rw-r--r-- | spec/finders/ci/runners_finder_spec.rb | 158 | ||||
-rw-r--r-- | spec/finders/error_tracking/errors_finder_spec.rb | 28 | ||||
-rw-r--r-- | spec/finders/group_members_finder_spec.rb | 6 | ||||
-rw-r--r-- | spec/finders/groups_finder_spec.rb | 31 | ||||
-rw-r--r-- | spec/finders/issues_finder_spec.rb | 162 | ||||
-rw-r--r-- | spec/finders/lfs_pointers_finder_spec.rb | 44 | ||||
-rw-r--r-- | spec/finders/merge_requests_finder_spec.rb | 12 | ||||
-rw-r--r-- | spec/finders/packages/pypi/packages_finder_spec.rb | 10 | ||||
-rw-r--r-- | spec/finders/projects/members/effective_access_level_per_user_finder_spec.rb | 38 |
10 files changed, 374 insertions, 138 deletions
diff --git a/spec/finders/ci/pipelines_finder_spec.rb b/spec/finders/ci/pipelines_finder_spec.rb index 16561aa65b6..c7bd52576e8 100644 --- a/spec/finders/ci/pipelines_finder_spec.rb +++ b/spec/finders/ci/pipelines_finder_spec.rb @@ -252,6 +252,29 @@ RSpec.describe Ci::PipelinesFinder do end end + context 'when source is specified' do + let(:params) { { source: 'web' } } + let!(:web_pipeline) { create(:ci_pipeline, project: project, source: 'web') } + let!(:push_pipeline) { create(:ci_pipeline, project: project, source: 'push') } + let!(:api_pipeline) { create(:ci_pipeline, project: project, source: 'api') } + + context 'when `pipeline_source_filter` feature flag is disabled' do + before do + stub_feature_flags(pipeline_source_filter: false) + end + + it 'returns all the pipelines' do + is_expected.to contain_exactly(web_pipeline, push_pipeline, api_pipeline) + end + end + + context 'when `pipeline_source_filter` feature flag is enabled' do + it 'returns only the matched pipeline' do + is_expected.to eq([web_pipeline]) + end + end + end + describe 'ordering' do using RSpec::Parameterized::TableSyntax diff --git a/spec/finders/ci/runners_finder_spec.rb b/spec/finders/ci/runners_finder_spec.rb index 7f05947ac48..599b4ffb804 100644 --- a/spec/finders/ci/runners_finder_spec.rb +++ b/spec/finders/ci/runners_finder_spec.rb @@ -33,41 +33,43 @@ RSpec.describe Ci::RunnersFinder do end end - context 'filter by search term' do - it 'calls Ci::Runner.search' do - expect(Ci::Runner).to receive(:search).with('term').and_call_original + context 'filtering' do + context 'by search term' do + it 'calls Ci::Runner.search' do + expect(Ci::Runner).to receive(:search).with('term').and_call_original - described_class.new(current_user: admin, params: { search: 'term' }).execute + described_class.new(current_user: admin, params: { search: 'term' }).execute + end end - end - context 'filter by status' do - Ci::Runner::AVAILABLE_STATUSES.each do |status| - it "calls the corresponding :#{status} scope on Ci::Runner" do - expect(Ci::Runner).to receive(status.to_sym).and_call_original + context 'by status' do + Ci::Runner::AVAILABLE_STATUSES.each do |status| + it "calls the corresponding :#{status} scope on Ci::Runner" do + expect(Ci::Runner).to receive(status.to_sym).and_call_original - described_class.new(current_user: admin, params: { status_status: status }).execute + described_class.new(current_user: admin, params: { status_status: status }).execute + end end end - end - context 'filter by runner type' do - it 'calls the corresponding scope on Ci::Runner' do - expect(Ci::Runner).to receive(:project_type).and_call_original + context 'by runner type' do + it 'calls the corresponding scope on Ci::Runner' do + expect(Ci::Runner).to receive(:project_type).and_call_original - described_class.new(current_user: admin, params: { type_type: 'project_type' }).execute + described_class.new(current_user: admin, params: { type_type: 'project_type' }).execute + end end - end - context 'filter by tag_name' do - it 'calls the corresponding scope on Ci::Runner' do - expect(Ci::Runner).to receive(:tagged_with).with(%w[tag1 tag2]).and_call_original + context 'by tag_name' do + it 'calls the corresponding scope on Ci::Runner' do + expect(Ci::Runner).to receive(:tagged_with).with(%w[tag1 tag2]).and_call_original - described_class.new(current_user: admin, params: { tag_name: %w[tag1 tag2] }).execute + described_class.new(current_user: admin, params: { tag_name: %w[tag1 tag2] }).execute + end end end - context 'sort' do + context 'sorting' do let_it_be(:runner1) { create :ci_runner, created_at: '2018-07-12 07:00', contacted_at: 1.minute.ago } let_it_be(:runner2) { create :ci_runner, created_at: '2018-07-12 08:00', contacted_at: 3.minutes.ago } let_it_be(:runner3) { create :ci_runner, created_at: '2018-07-12 09:00', contacted_at: 2.minutes.ago } @@ -121,7 +123,7 @@ RSpec.describe Ci::RunnersFinder do end end - context 'non admin user' do + context 'by non admin user' do it 'returns no runners' do user = create :user create :ci_runner, active: true @@ -131,7 +133,7 @@ RSpec.describe Ci::RunnersFinder do end end - context 'user is nil' do + context 'when user is nil' do it 'returns no runners' do user = nil create :ci_runner, active: true @@ -182,85 +184,69 @@ RSpec.describe Ci::RunnersFinder do describe '#execute' do subject { described_class.new(current_user: user, group: group, params: params).execute } - context 'no params' do + context 'with user as group owner' do before do group.add_owner(user) end - it 'returns all runners' do - expect(subject).to eq([runner_project_7, runner_project_6, runner_project_5, - runner_project_4, runner_project_3, runner_project_2, - runner_project_1, runner_sub_group_4, runner_sub_group_3, - runner_sub_group_2, runner_sub_group_1, runner_group]) - end - end - - context 'with sort param' do - let(:params) { { sort: 'contacted_asc' } } - - before do - group.add_owner(user) - end - - it 'sorts by specified attribute' do - expect(subject).to eq([runner_group, runner_sub_group_1, runner_sub_group_2, - runner_sub_group_3, runner_sub_group_4, runner_project_1, - runner_project_2, runner_project_3, runner_project_4, - runner_project_5, runner_project_6, runner_project_7]) + context 'passing no params' do + it 'returns all descendant runners' do + expect(subject).to eq([runner_project_7, runner_project_6, runner_project_5, + runner_project_4, runner_project_3, runner_project_2, + runner_project_1, runner_sub_group_4, runner_sub_group_3, + runner_sub_group_2, runner_sub_group_1, runner_group]) + end end - end - - context 'filter by search term' do - let(:params) { { search: 'runner_project_search' } } - before do - group.add_owner(user) - end + context 'with sort param' do + let(:params) { { sort: 'contacted_asc' } } - it 'returns correct runner' do - expect(subject).to eq([runner_project_3]) + it 'sorts by specified attribute' do + expect(subject).to eq([runner_group, runner_sub_group_1, runner_sub_group_2, + runner_sub_group_3, runner_sub_group_4, runner_project_1, + runner_project_2, runner_project_3, runner_project_4, + runner_project_5, runner_project_6, runner_project_7]) + end end - end - context 'filter by status' do - let(:params) { { status_status: 'paused' } } + context 'filtering' do + context 'by search term' do + let(:params) { { search: 'runner_project_search' } } - before do - group.add_owner(user) - end - - it 'returns correct runner' do - expect(subject).to eq([runner_sub_group_1]) - end - end + it 'returns correct runner' do + expect(subject).to eq([runner_project_3]) + end + end - context 'filter by tag_name' do - let(:params) { { tag_name: %w[runner_tag] } } + context 'by status' do + let(:params) { { status_status: 'paused' } } - before do - group.add_owner(user) - end + it 'returns correct runner' do + expect(subject).to eq([runner_sub_group_1]) + end + end - it 'returns correct runner' do - expect(subject).to eq([runner_project_5]) - end - end + context 'by tag_name' do + let(:params) { { tag_name: %w[runner_tag] } } - context 'filter by runner type' do - let(:params) { { type_type: 'project_type' } } + it 'returns correct runner' do + expect(subject).to eq([runner_project_5]) + end + end - before do - group.add_owner(user) - end + context 'by runner type' do + let(:params) { { type_type: 'project_type' } } - it 'returns correct runners' do - expect(subject).to eq([runner_project_7, runner_project_6, - runner_project_5, runner_project_4, - runner_project_3, runner_project_2, runner_project_1]) + it 'returns correct runners' do + expect(subject).to eq([runner_project_7, runner_project_6, + runner_project_5, runner_project_4, + runner_project_3, runner_project_2, runner_project_1]) + end + end end end - context 'user has no access to runners' do + context 'when user is not group owner' do where(:user_permission) do [:maintainer, :developer, :reporter, :guest] end @@ -276,13 +262,13 @@ RSpec.describe Ci::RunnersFinder do end end - context 'user with no access' do + context 'when user has no access' do it 'returns no runners' do expect(subject).to be_empty end end - context 'user is nil' do + context 'when user is nil' do let_it_be(:user) { nil } it 'returns no runners' do @@ -294,7 +280,7 @@ RSpec.describe Ci::RunnersFinder do describe '#sort_key' do subject { described_class.new(current_user: user, group: group, params: params).sort_key } - context 'no params' do + context 'without params' do it 'returns created_at_desc' do expect(subject).to eq('created_at_desc') end diff --git a/spec/finders/error_tracking/errors_finder_spec.rb b/spec/finders/error_tracking/errors_finder_spec.rb new file mode 100644 index 00000000000..2df5f1653e0 --- /dev/null +++ b/spec/finders/error_tracking/errors_finder_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ErrorTracking::ErrorsFinder do + let_it_be(:project) { create(:project) } + let_it_be(:user) { project.creator } + let_it_be(:error) { create(:error_tracking_error, project: project) } + let_it_be(:error_resolved) { create(:error_tracking_error, :resolved, project: project) } + + before do + project.add_maintainer(user) + end + + describe '#execute' do + let(:params) { {} } + + subject { described_class.new(user, project, params).execute } + + it { is_expected.to contain_exactly(error, error_resolved) } + + context 'with status parameter' do + let(:params) { { status: 'resolved' } } + + it { is_expected.to contain_exactly(error_resolved) } + end + end +end diff --git a/spec/finders/group_members_finder_spec.rb b/spec/finders/group_members_finder_spec.rb index 3238f6744f7..0d797b7923c 100644 --- a/spec/finders/group_members_finder_spec.rb +++ b/spec/finders/group_members_finder_spec.rb @@ -38,6 +38,12 @@ RSpec.describe GroupMembersFinder, '#execute' do } end + it 'raises an error if a non-supported relation type is used' do + expect do + described_class.new(group).execute(include_relations: [:direct, :invalid_relation_type]) + end.to raise_error(ArgumentError, "invalid_relation_type is not a valid relation type. Valid relation types are direct, inherited, descendants.") + end + using RSpec::Parameterized::TableSyntax where(:subject_relations, :subject_group, :expected_members) do diff --git a/spec/finders/groups_finder_spec.rb b/spec/finders/groups_finder_spec.rb index 481e2983dd7..10a08d7326e 100644 --- a/spec/finders/groups_finder_spec.rb +++ b/spec/finders/groups_finder_spec.rb @@ -229,5 +229,36 @@ RSpec.describe GroupsFinder do end end end + + context 'with search' do + let_it_be(:parent_group) { create(:group, :public, name: 'Parent Group') } + let_it_be(:test_group) { create(:group, :public, path: 'test-path') } + + it 'returns all groups with matching title' do + expect(described_class.new(user, { search: 'parent' }).execute).to contain_exactly(parent_group) + end + + it 'returns all groups with matching path' do + expect(described_class.new(user, { search: 'test' }).execute).to contain_exactly(test_group) + end + + it 'does not search in full path if parent is set' do + matching_subgroup = create(:group, parent: parent_group, path: "#{parent_group.path}-subgroup") + + expect(described_class.new(user, { search: 'parent', parent: parent_group }).execute).to contain_exactly(matching_subgroup) + end + + context 'with group descendants' do + let_it_be(:sub_group) { create(:group, :public, name: 'Sub Group', parent: parent_group) } + + let(:params) { { search: parent_group.path } } + + it 'searches in full path if descendant groups are not included' do + params[:include_parent_descendants] = false + + expect(described_class.new(user, params).execute).to contain_exactly(parent_group, sub_group) + end + end + end end end diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index 1c8c2af8e03..0cb73f3da6d 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -789,7 +789,7 @@ RSpec.describe IssuesFinder do context 'user filters confidential issues' do let(:params) { { confidential: true } } - it 'returns only confdential issues' do + it 'returns only confidential issues' do expect(issues).to contain_exactly(confidential_issue) end end @@ -797,7 +797,7 @@ RSpec.describe IssuesFinder do context 'user filters only public issues' do let(:params) { { confidential: false } } - it 'returns only confdential issues' do + it 'returns only public issues' do expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5) end end @@ -1004,9 +1004,38 @@ RSpec.describe IssuesFinder do let(:guest) { create(:user) } let_it_be(:authorized_user) { create(:user) } + let_it_be(:banned_user) { create(:user, :banned) } let_it_be(:project) { create(:project, namespace: authorized_user.namespace) } let_it_be(:public_issue) { create(:issue, project: project) } let_it_be(:confidential_issue) { create(:issue, project: project, confidential: true) } + let_it_be(:hidden_issue) { create(:issue, project: project, author: banned_user) } + + shared_examples 'returns public, does not return hidden or confidential' do + it 'returns only public issues' do + expect(subject).to include(public_issue) + expect(subject).not_to include(confidential_issue, hidden_issue) + end + end + + shared_examples 'returns public and confidential, does not return hidden' do + it 'returns only public and confidential issues' do + expect(subject).to include(public_issue, confidential_issue) + expect(subject).not_to include(hidden_issue) + end + end + + shared_examples 'returns public and hidden, does not return confidential' do + it 'returns only public and hidden issues' do + expect(subject).to include(public_issue, hidden_issue) + expect(subject).not_to include(confidential_issue) + end + end + + shared_examples 'returns public, confidential, and hidden' do + it 'returns all issues' do + expect(subject).to include(public_issue, confidential_issue, hidden_issue) + end + end context 'when no project filter is given' do let(:params) { {} } @@ -1014,18 +1043,28 @@ RSpec.describe IssuesFinder do context 'for an anonymous user' do subject { described_class.new(nil, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end context 'for a user without project membership' do subject { described_class.new(user, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end @@ -1036,17 +1075,28 @@ RSpec.describe IssuesFinder do project.add_guest(guest) end - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end context 'for a project member with access to view confidential issues' do subject { described_class.new(authorized_user, params).with_confidentiality_access_check } - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public and confidential, does not return hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end end @@ -1056,15 +1106,26 @@ RSpec.describe IssuesFinder do subject { described_class.new(admin_user, params).with_confidentiality_access_check } context 'when admin mode is enabled', :enable_admin_mode do - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public, confidential, and hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end end context 'when admin mode is disabled' do - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end end end @@ -1076,14 +1137,18 @@ RSpec.describe IssuesFinder do context 'for an anonymous user' do subject { described_class.new(nil, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'does not filter by confidentiality' do expect(Issue).not_to receive(:where).with(a_string_matching('confidential'), anything) - subject end end @@ -1091,9 +1156,14 @@ RSpec.describe IssuesFinder do context 'for a user without project membership' do subject { described_class.new(user, params).with_confidentiality_access_check } - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'filters by confidentiality' do @@ -1108,9 +1178,14 @@ RSpec.describe IssuesFinder do project.add_guest(guest) end - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'filters by confidentiality' do @@ -1121,8 +1196,14 @@ RSpec.describe IssuesFinder do context 'for a project member with access to view confidential issues' do subject { described_class.new(authorized_user, params).with_confidentiality_access_check } - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public and confidential, does not return hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end it 'does not filter by confidentiality' do @@ -1138,8 +1219,14 @@ RSpec.describe IssuesFinder do subject { described_class.new(admin_user, params).with_confidentiality_access_check } context 'when admin mode is enabled', :enable_admin_mode do - it 'returns all issues' do - expect(subject).to include(public_issue, confidential_issue) + it_behaves_like 'returns public, confidential, and hidden' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public, confidential, and hidden' end it 'does not filter by confidentiality' do @@ -1150,9 +1237,14 @@ RSpec.describe IssuesFinder do end context 'when admin mode is disabled' do - it 'returns only public issues' do - expect(subject).to include(public_issue) - expect(subject).not_to include(confidential_issue) + it_behaves_like 'returns public, does not return hidden or confidential' + + context 'when feature flag is disabled' do + before do + stub_feature_flags(ban_user_feature_flag: false) + end + + it_behaves_like 'returns public and hidden, does not return confidential' end it 'filters by confidentiality' do diff --git a/spec/finders/lfs_pointers_finder_spec.rb b/spec/finders/lfs_pointers_finder_spec.rb new file mode 100644 index 00000000000..2f45f383f2f --- /dev/null +++ b/spec/finders/lfs_pointers_finder_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe LfsPointersFinder do + subject(:finder) { described_class.new(repository, path) } + + let_it_be(:project) { create(:project, :repository) } + let_it_be(:repository) { project.repository } + + let(:path) { nil } + + describe '#execute' do + subject { finder.execute } + + let(:expected_blob_id) { '0c304a93cb8430108629bbbcaa27db3343299bc0' } + + context 'when path has no LFS files' do + it { is_expected.to eq([]) } + end + + context 'when path points to LFS file' do + let(:path) { 'files/lfs/lfs_object.iso' } + + it 'returns LFS blob ids' do + is_expected.to eq([expected_blob_id]) + end + end + + context 'when path points to directory with LFS files' do + let(:path) { 'files/lfs/' } + + it 'returns LFS blob ids' do + is_expected.to eq([expected_blob_id]) + end + end + + context 'when repository is empty' do + let(:project) { create(:project, :empty_repo) } + + it { is_expected.to eq([]) } + end + end +end diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb index c2ea918449c..49b29cefb9b 100644 --- a/spec/finders/merge_requests_finder_spec.rb +++ b/spec/finders/merge_requests_finder_spec.rb @@ -317,18 +317,6 @@ RSpec.describe MergeRequestsFinder do ) end - context 'when merge_request_draft_filter is disabled' do - it 'does not include draft merge requests' do - stub_feature_flags(merge_request_draft_filter: false) - - merge_requests = described_class.new(user, { draft_param_key => 'yes' }).execute - - expect(merge_requests).to contain_exactly( - merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4 - ) - end - end - it "filters by not #{draft_param_key}" do params = { draft_param_key => 'no' } diff --git a/spec/finders/packages/pypi/packages_finder_spec.rb b/spec/finders/packages/pypi/packages_finder_spec.rb index a69c2317261..1a44fb99009 100644 --- a/spec/finders/packages/pypi/packages_finder_spec.rb +++ b/spec/finders/packages/pypi/packages_finder_spec.rb @@ -14,14 +14,14 @@ RSpec.describe Packages::Pypi::PackagesFinder do let(:package_name) { package2.name } - describe 'execute!' do - subject { described_class.new(user, scope, package_name: package_name).execute! } + describe 'execute' do + subject { described_class.new(user, scope, package_name: package_name).execute } shared_examples 'when no package is found' do context 'non-existing package' do let(:package_name) { 'none' } - it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } + it { expect(subject).to be_empty } end end @@ -29,7 +29,7 @@ RSpec.describe Packages::Pypi::PackagesFinder do context 'non-existing package' do let(:package_name) { package2.name.upcase.tr('-', '.') } - it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } + it { expect(subject).to be_empty } end end @@ -45,7 +45,7 @@ RSpec.describe Packages::Pypi::PackagesFinder do context 'within a group' do let(:scope) { group } - it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } + it { expect(subject).to be_empty } context 'user with access to only one project' do before do diff --git a/spec/finders/projects/members/effective_access_level_per_user_finder_spec.rb b/spec/finders/projects/members/effective_access_level_per_user_finder_spec.rb new file mode 100644 index 00000000000..3872938d20e --- /dev/null +++ b/spec/finders/projects/members/effective_access_level_per_user_finder_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe Projects::Members::EffectiveAccessLevelPerUserFinder, '#execute' do + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:user) { create(:user) } + + # The result set is being converted to json just for the ease of testing. + subject { described_class.new(project, user).execute.as_json } + + context 'a combination of all possible avenues of membership' do + let_it_be(:another_user) { create(:user) } + let_it_be(:shared_with_group) { create(:group) } + + before do + create(:project_group_link, :maintainer, project: project, group: shared_with_group) + create(:group_group_link, :reporter, shared_group: project.group, shared_with_group: shared_with_group) + + shared_with_group.add_maintainer(user) + shared_with_group.add_maintainer(another_user) + group.add_guest(user) + group.add_guest(another_user) + project.add_developer(user) + project.add_developer(another_user) + end + + it 'includes the highest access level from all avenues of memberships for the specific user alone' do + expect(subject).to eq( + [{ + 'user_id' => user.id, + 'access_level' => Gitlab::Access::MAINTAINER, # From project_group_link + 'id' => nil + }] + ) + end + end +end |