diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-16 18:18:33 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-16 18:18:33 +0000 |
commit | f64a639bcfa1fc2bc89ca7db268f594306edfd7c (patch) | |
tree | a2c3c2ebcc3b45e596949db485d6ed18ffaacfa1 /spec/finders | |
parent | bfbc3e0d6583ea1a91f627528bedc3d65ba4b10f (diff) | |
download | gitlab-ce-f64a639bcfa1fc2bc89ca7db268f594306edfd7c.tar.gz |
Add latest changes from gitlab-org/gitlab@13-10-stable-eev13.10.0-rc40
Diffstat (limited to 'spec/finders')
19 files changed, 698 insertions, 242 deletions
diff --git a/spec/finders/admin/plans_finder_spec.rb b/spec/finders/admin/plans_finder_spec.rb new file mode 100644 index 00000000000..9ea5944147c --- /dev/null +++ b/spec/finders/admin/plans_finder_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Admin::PlansFinder do + let_it_be(:plan1) { create(:plan, name: 'plan1') } + let_it_be(:plan2) { create(:plan, name: 'plan2') } + + describe '#execute' do + context 'with no params' do + it 'returns all plans' do + found = described_class.new.execute + + expect(found).to match_array([plan1, plan2]) + end + end + + context 'with missing name in params' do + before do + @params = { title: 'plan2' } + end + + it 'returns all plans' do + found = described_class.new(@params).execute + + expect(found).to match_array([plan1, plan2]) + end + end + + context 'with existing name in params' do + before do + @params = { name: 'plan2' } + end + + it 'returns the plan' do + found = described_class.new(@params).execute + + expect(found).to match(plan2) + end + end + + context 'with non-existing name in params' do + before do + @params = { name: 'non-existing-plan' } + end + + it 'returns nil' do + found = described_class.new(@params).execute + + expect(found).to be_nil + end + end + end +end diff --git a/spec/finders/boards/boards_finder_spec.rb b/spec/finders/boards/boards_finder_spec.rb new file mode 100644 index 00000000000..2249c69df1b --- /dev/null +++ b/spec/finders/boards/boards_finder_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Boards::BoardsFinder do + describe '#execute' do + context 'when board parent is a project' do + let(:parent) { create(:project) } + + subject(:service) { described_class.new(parent, double) } + + it_behaves_like 'boards list service' + it_behaves_like 'multiple boards list service' + end + + context 'when board parent is a group' do + let(:parent) { create(:group) } + + subject(:service) { described_class.new(parent, double) } + + it_behaves_like 'boards list service' + end + end +end diff --git a/spec/finders/ci/daily_build_group_report_results_finder_spec.rb b/spec/finders/ci/daily_build_group_report_results_finder_spec.rb index 2a6e44673e3..cf15a00323b 100644 --- a/spec/finders/ci/daily_build_group_report_results_finder_spec.rb +++ b/spec/finders/ci/daily_build_group_report_results_finder_spec.rb @@ -5,10 +5,14 @@ require 'spec_helper' RSpec.describe Ci::DailyBuildGroupReportResultsFinder do describe '#execute' do let_it_be(:project) { create(:project, :private) } - let_it_be(:current_user) { project.owner } + let(:user_without_permission) { create(:user) } + let_it_be(:user_with_permission) { project.owner } let_it_be(:ref_path) { 'refs/heads/master' } let(:limit) { nil } let_it_be(:default_branch) { false } + let(:start_date) { '2020-03-09' } + let(:end_date) { '2020-03-10' } + let(:sort) { true } let_it_be(:rspec_coverage_1) { create_daily_coverage('rspec', 79.0, '2020-03-09') } let_it_be(:karma_coverage_1) { create_daily_coverage('karma', 89.0, '2020-03-09') } @@ -17,24 +21,35 @@ RSpec.describe Ci::DailyBuildGroupReportResultsFinder do let_it_be(:rspec_coverage_3) { create_daily_coverage('rspec', 97.0, '2020-03-11') } let_it_be(:karma_coverage_3) { create_daily_coverage('karma', 99.0, '2020-03-11') } - let(:attributes) do + let(:finder) { described_class.new(params: params, current_user: current_user) } + + let(:params) do { - current_user: current_user, project: project, + coverage: true, ref_path: ref_path, - start_date: '2020-03-09', - end_date: '2020-03-10', - limit: limit + start_date: start_date, + end_date: end_date, + limit: limit, + sort: sort } end - subject(:coverages) do - described_class.new(**attributes).execute - end + subject(:coverages) { finder.execute } + + context 'when params are provided' do + context 'when current user is not allowed to read data' do + let(:current_user) { user_without_permission } + + it 'returns an empty collection' do + expect(coverages).to be_empty + end + end + + context 'when current user is allowed to read data' do + let(:current_user) { user_with_permission } - context 'when ref_path is present' do - context 'when current user is allowed to read build report results' do - it 'returns all matching results within the given date range' do + it 'returns matching coverages within the given date range' do expect(coverages).to match_array([ karma_coverage_2, rspec_coverage_2, @@ -43,37 +58,45 @@ RSpec.describe Ci::DailyBuildGroupReportResultsFinder do ]) end - context 'and limit is specified' do + context 'when ref_path is nil' do + let(:default_branch) { true } + let(:ref_path) { nil } + + it 'returns coverages for the default branch' do + rspec_coverage_4 = create_daily_coverage('rspec', 66.0, '2020-03-10') + + expect(coverages).to contain_exactly(rspec_coverage_4) + end + end + + context 'when limit is specified' do let(:limit) { 2 } - it 'returns limited number of matching results within the given date range' do + it 'returns limited number of matching coverages within the given date range' do expect(coverages).to match_array([ karma_coverage_2, rspec_coverage_2 ]) end end - end - - context 'when current user is not allowed to read build report results' do - let(:current_user) { create(:user) } - - it 'returns an empty result' do - expect(coverages).to be_empty - end - end - end - - context 'when ref_path query parameter is not present' do - let(:ref_path) { nil } - context 'when records with cover data from the default branch exist' do - let(:default_branch) { true } - - it 'returns records with default_branch:true, irrespective of ref_path' do - rspec_coverage_4 = create_daily_coverage('rspec', 66.0, '2020-03-10') - - expect(coverages).to contain_exactly(rspec_coverage_4) + context 'when provided dates are nil' do + let(:start_date) { nil } + let(:end_date) { nil } + let(:rspec_coverage_4) { create_daily_coverage('rspec', 98.0, 91.days.ago.to_date.to_s) } + + it 'returns all coverages from the last 90 days' do + expect(coverages).to match_array( + [ + karma_coverage_3, + rspec_coverage_3, + karma_coverage_2, + rspec_coverage_2, + karma_coverage_1, + rspec_coverage_1 + ] + ) + end end end end diff --git a/spec/finders/ci/testing/daily_build_group_report_results_finder_spec.rb b/spec/finders/ci/testing/daily_build_group_report_results_finder_spec.rb deleted file mode 100644 index a703f3b800c..00000000000 --- a/spec/finders/ci/testing/daily_build_group_report_results_finder_spec.rb +++ /dev/null @@ -1,99 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Ci::Testing::DailyBuildGroupReportResultsFinder do - describe '#execute' do - let_it_be(:project) { create(:project, :private) } - let(:user_without_permission) { create(:user) } - let_it_be(:user_with_permission) { project.owner } - let_it_be(:ref_path) { 'refs/heads/master' } - let(:limit) { nil } - let_it_be(:default_branch) { false } - let(:start_date) { '2020-03-09' } - let(:end_date) { '2020-03-10' } - let(:sort) { true } - - let_it_be(:rspec_coverage_1) { create_daily_coverage('rspec', 79.0, '2020-03-09') } - let_it_be(:karma_coverage_1) { create_daily_coverage('karma', 89.0, '2020-03-09') } - let_it_be(:rspec_coverage_2) { create_daily_coverage('rspec', 95.0, '2020-03-10') } - let_it_be(:karma_coverage_2) { create_daily_coverage('karma', 92.0, '2020-03-10') } - let_it_be(:rspec_coverage_3) { create_daily_coverage('rspec', 97.0, '2020-03-11') } - let_it_be(:karma_coverage_3) { create_daily_coverage('karma', 99.0, '2020-03-11') } - - let(:finder) { described_class.new(params: params, current_user: current_user) } - - let(:params) do - { - project: project, - coverage: true, - ref_path: ref_path, - start_date: start_date, - end_date: end_date, - limit: limit, - sort: sort - } - end - - subject(:coverages) { finder.execute } - - context 'when params are provided' do - context 'when current user is not allowed to read data' do - let(:current_user) { user_without_permission } - - it 'returns an empty collection' do - expect(coverages).to be_empty - end - end - - context 'when current user is allowed to read data' do - let(:current_user) { user_with_permission } - - it 'returns matching coverages within the given date range' do - expect(coverages).to match_array([ - karma_coverage_2, - rspec_coverage_2, - karma_coverage_1, - rspec_coverage_1 - ]) - end - - context 'when ref_path is nil' do - let(:default_branch) { true } - let(:ref_path) { nil } - - it 'returns coverages for the default branch' do - rspec_coverage_4 = create_daily_coverage('rspec', 66.0, '2020-03-10') - - expect(coverages).to contain_exactly(rspec_coverage_4) - end - end - - context 'when limit is specified' do - let(:limit) { 2 } - - it 'returns limited number of matching coverages within the given date range' do - expect(coverages).to match_array([ - karma_coverage_2, - rspec_coverage_2 - ]) - end - end - end - end - end - - private - - def create_daily_coverage(group_name, coverage, date) - create( - :ci_daily_build_group_report_result, - project: project, - ref_path: ref_path || 'feature-branch', - group_name: group_name, - data: { 'coverage' => coverage }, - date: date, - default_branch: default_branch - ) - end -end diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index 33b8a5954ae..b794ab626bf 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -179,33 +179,54 @@ RSpec.describe IssuesFinder do end end - context 'filtering by author ID' do - let(:params) { { author_id: user2.id } } + context 'filtering by author' do + context 'by author ID' do + let(:params) { { author_id: user2.id } } - it 'returns issues created by that user' do - expect(issues).to contain_exactly(issue3) + it 'returns issues created by that user' do + expect(issues).to contain_exactly(issue3) + end end - end - context 'filtering by not author ID' do - let(:params) { { not: { author_id: user2.id } } } + context 'using OR' do + let(:issue6) { create(:issue, project: project2) } + let(:params) { { or: { author_username: [issue3.author.username, issue6.author.username] } } } + + it 'returns issues created by any of the given users' do + expect(issues).to contain_exactly(issue3, issue6) + end + + context 'when feature flag is disabled' do + before do + stub_feature_flags(or_issuable_queries: false) + end - it 'returns issues not created by that user' do - expect(issues).to contain_exactly(issue1, issue2, issue4, issue5) + it 'does not add any filter' do + expect(issues).to contain_exactly(issue1, issue2, issue3, issue4, issue5, issue6) + end + end end - end - context 'filtering by nonexistent author ID and issue term using CTE for search' do - let(:params) do - { - author_id: 'does-not-exist', - search: 'git', - attempt_group_search_optimizations: true - } + context 'filtering by NOT author ID' do + let(:params) { { not: { author_id: user2.id } } } + + it 'returns issues not created by that user' do + expect(issues).to contain_exactly(issue1, issue2, issue4, issue5) + end end - it 'returns no results' do - expect(issues).to be_empty + context 'filtering by nonexistent author ID and issue term using CTE for search' do + let(:params) do + { + author_id: 'does-not-exist', + search: 'git', + attempt_group_search_optimizations: true + } + end + + it 'returns no results' do + expect(issues).to be_empty + end end end diff --git a/spec/finders/merge_request_target_project_finder_spec.rb b/spec/finders/merge_request_target_project_finder_spec.rb index dfb4d86fbb6..08fbfd7229a 100644 --- a/spec/finders/merge_request_target_project_finder_spec.rb +++ b/spec/finders/merge_request_target_project_finder_spec.rb @@ -16,13 +16,22 @@ RSpec.describe MergeRequestTargetProjectFinder do expect(finder.execute).to contain_exactly(base_project, other_fork, forked_project) end - it 'does not include projects that have merge requests turned off' do + it 'does not include projects that have merge requests turned off by default' do other_fork.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) base_project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) expect(finder.execute).to contain_exactly(forked_project) end + it 'includes projects that have merge requests turned off by default with a more-permissive project feature' do + finder = described_class.new(current_user: user, source_project: forked_project, project_feature: :repository) + + other_fork.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) + base_project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED) + + expect(finder.execute).to contain_exactly(base_project, other_fork, forked_project) + end + it 'does not contain archived projects' do base_project.update!(archived: true) diff --git a/spec/finders/merge_requests/oldest_per_commit_finder_spec.rb b/spec/finders/merge_requests/oldest_per_commit_finder_spec.rb index 4e9d021fa5d..4724a8eb5c7 100644 --- a/spec/finders/merge_requests/oldest_per_commit_finder_spec.rb +++ b/spec/finders/merge_requests/oldest_per_commit_finder_spec.rb @@ -6,12 +6,20 @@ RSpec.describe MergeRequests::OldestPerCommitFinder do describe '#execute' do it 'returns a Hash mapping commit SHAs to their oldest merge requests' do project = create(:project) + sha1 = Digest::SHA1.hexdigest('foo') + sha2 = Digest::SHA1.hexdigest('bar') + sha3 = Digest::SHA1.hexdigest('baz') mr1 = create(:merge_request, :merged, target_project: project) mr2 = create(:merge_request, :merged, target_project: project) + mr3 = create( + :merge_request, + :merged, + target_project: project, + merge_commit_sha: sha3 + ) + mr1_diff = create(:merge_request_diff, merge_request: mr1) mr2_diff = create(:merge_request_diff, merge_request: mr2) - sha1 = Digest::SHA1.hexdigest('foo') - sha2 = Digest::SHA1.hexdigest('bar') create(:merge_request_diff_commit, merge_request_diff: mr1_diff, sha: sha1) create(:merge_request_diff_commit, merge_request_diff: mr2_diff, sha: sha1) @@ -22,11 +30,16 @@ RSpec.describe MergeRequests::OldestPerCommitFinder do relative_order: 1 ) - commits = [double(:commit, id: sha1), double(:commit, id: sha2)] + commits = [ + double(:commit, id: sha1), + double(:commit, id: sha2), + double(:commit, id: sha3) + ] expect(described_class.new(project).execute(commits)).to eq( sha1 => mr1, - sha2 => mr2 + sha2 => mr2, + sha3 => mr3 ) end @@ -42,5 +55,45 @@ RSpec.describe MergeRequests::OldestPerCommitFinder do expect(described_class.new(mr.target_project).execute(commits)) .to be_empty end + + it 'includes the merge request for a merge commit' do + project = create(:project) + sha = Digest::SHA1.hexdigest('foo') + mr = create( + :merge_request, + :merged, + target_project: project, + merge_commit_sha: sha + ) + + commits = [double(:commit, id: sha)] + + # This expectation is set so we're certain that the merge commit SHAs (if + # a matching merge request is found) aren't also used for finding MRs + # according to diffs. + expect(MergeRequestDiffCommit) + .not_to receive(:oldest_merge_request_id_per_commit) + + expect(described_class.new(project).execute(commits)).to eq(sha => mr) + end + + it 'includes the oldest merge request when a merge commit is present in a newer merge request' do + project = create(:project) + sha = Digest::SHA1.hexdigest('foo') + mr1 = create( + :merge_request, + :merged, + target_project: project, merge_commit_sha: sha + ) + + mr2 = create(:merge_request, :merged, target_project: project) + mr_diff = create(:merge_request_diff, merge_request: mr2) + + create(:merge_request_diff_commit, merge_request_diff: mr_diff, sha: sha) + + commits = [double(:commit, id: sha)] + + expect(described_class.new(project).execute(commits)).to eq(sha => mr1) + end end end diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb index 6fdfe780463..b3000498bb6 100644 --- a/spec/finders/merge_requests_finder_spec.rb +++ b/spec/finders/merge_requests_finder_spec.rb @@ -41,30 +41,51 @@ RSpec.describe MergeRequestsFinder do expect(merge_requests).to contain_exactly(merge_request1) end - it 'filters by nonexistent author ID and MR term using CTE for search' do - params = { - author_id: 'does-not-exist', - search: 'git', - attempt_group_search_optimizations: true - } + context 'filtering by author' do + subject(:merge_requests) { described_class.new(user, params).execute } - merge_requests = described_class.new(user, params).execute + context 'using OR' do + let(:params) { { or: { author_username: [merge_request1.author.username, merge_request2.author.username] } } } - expect(merge_requests).to be_empty - end + before do + merge_request1.update!(author: create(:user)) + merge_request2.update!(author: create(:user)) + end + + it 'returns merge requests created by any of the given users' do + expect(merge_requests).to contain_exactly(merge_request1, merge_request2) + end - context 'filtering by not author ID' do - let(:params) { { not: { author_id: user2.id } } } + context 'when feature flag is disabled' do + before do + stub_feature_flags(or_issuable_queries: false) + end - before do - merge_request2.update!(author: user2) - merge_request3.update!(author: user2) + it 'does not add any filter' do + expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request4, merge_request5) + end + end end - it 'returns merge requests not created by that user' do - merge_requests = described_class.new(user, params).execute + context 'with nonexistent author ID and MR term using CTE for search' do + let(:params) { { author_id: 'does-not-exist', search: 'git', attempt_group_search_optimizations: true } } + + it 'returns no results' do + expect(merge_requests).to be_empty + end + end - expect(merge_requests).to contain_exactly(merge_request1, merge_request4, merge_request5) + context 'filtering by not author ID' do + let(:params) { { not: { author_id: user2.id } } } + + before do + merge_request2.update!(author: user2) + merge_request3.update!(author: user2) + end + + it 'returns merge requests not created by that user' do + expect(merge_requests).to contain_exactly(merge_request1, merge_request4, merge_request5) + end end end diff --git a/spec/finders/namespaces/projects_finder_spec.rb b/spec/finders/namespaces/projects_finder_spec.rb new file mode 100644 index 00000000000..0f48aa6a9f4 --- /dev/null +++ b/spec/finders/namespaces/projects_finder_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Namespaces::ProjectsFinder do + let_it_be(:current_user) { create(:user) } + let_it_be(:namespace) { create(:group, :public) } + let_it_be(:subgroup) { create(:group, parent: namespace) } + let_it_be(:project_1) { create(:project, :public, group: namespace, path: 'project', name: 'Project') } + let_it_be(:project_2) { create(:project, :public, group: namespace, path: 'test-project', name: 'Test Project') } + let_it_be(:project_3) { create(:project, :public, path: 'sub-test-project', group: subgroup, name: 'Sub Test Project') } + let_it_be(:project_4) { create(:project, :public, path: 'test-project-2', group: namespace, name: 'Test Project 2') } + + let(:params) { {} } + + let(:finder) { described_class.new(namespace: namespace, params: params, current_user: current_user) } + + subject(:projects) { finder.execute } + + describe '#execute' do + context 'without a namespace' do + let(:namespace) { nil } + + it 'returns an empty array' do + expect(projects).to be_empty + end + end + + context 'with a namespace' do + it 'returns the project for the namespace' do + expect(projects).to contain_exactly(project_1, project_2, project_4) + end + + context 'when include_subgroups is provided' do + let(:params) { { include_subgroups: true } } + + it 'returns all projects for the namespace' do + expect(projects).to contain_exactly(project_1, project_2, project_3, project_4) + end + + context 'when ids are provided' do + let(:params) { { include_subgroups: true, ids: [project_3.id] } } + + it 'returns all projects for the ids' do + expect(projects).to contain_exactly(project_3) + end + end + end + + context 'when ids are provided' do + let(:params) { { ids: [project_1.id] } } + + it 'returns all projects for the ids' do + expect(projects).to contain_exactly(project_1) + end + end + + context 'when sort is similarity' do + let(:params) { { sort: :similarity, search: 'test' } } + + it 'returns projects by similarity' do + expect(projects).to contain_exactly(project_2, project_4) + end + end + + context 'when search parameter is missing' do + let(:params) { { sort: :similarity } } + + it 'returns all projects' do + expect(projects).to contain_exactly(project_1, project_2, project_4) + end + end + + context 'when sort parameter is missing' do + let(:params) { { search: 'test' } } + + it 'returns matching projects' do + expect(projects).to contain_exactly(project_2, project_4) + end + end + end + end +end diff --git a/spec/finders/packages/group_packages_finder_spec.rb b/spec/finders/packages/group_packages_finder_spec.rb index 445482a5a96..d6daf73aba2 100644 --- a/spec/finders/packages/group_packages_finder_spec.rb +++ b/spec/finders/packages/group_packages_finder_spec.rb @@ -122,7 +122,7 @@ RSpec.describe Packages::GroupPackagesFinder do end context 'when there are processing packages' do - let_it_be(:package4) { create(:nuget_package, project: project, name: Packages::Nuget::CreatePackageService::TEMPORARY_PACKAGE_NAME) } + let_it_be(:package4) { create(:nuget_package, project: project, name: Packages::Nuget::TEMPORARY_PACKAGE_NAME) } it { is_expected.to match_array([package1, package2]) } end diff --git a/spec/finders/packages/npm/package_finder_spec.rb b/spec/finders/packages/npm/package_finder_spec.rb index 78c23971f92..f021d800f31 100644 --- a/spec/finders/packages/npm/package_finder_spec.rb +++ b/spec/finders/packages/npm/package_finder_spec.rb @@ -2,39 +2,139 @@ require 'spec_helper' RSpec.describe ::Packages::Npm::PackageFinder do - let(:package) { create(:npm_package) } + let_it_be_with_reload(:project) { create(:project)} + let_it_be(:package) { create(:npm_package, project: project) } + let(:project) { package.project } let(:package_name) { package.name } - describe '#execute!' do - subject { described_class.new(project, package_name).execute } + shared_examples 'accepting a namespace for' do |example_name| + before do + project.update!(namespace: namespace) + end + + context 'that is a group' do + let_it_be(:namespace) { create(:group) } + + it_behaves_like example_name + + context 'within another group' do + let_it_be(:subgroup) { create(:group, parent: namespace) } + + before do + project.update!(namespace: subgroup) + end + + it_behaves_like example_name + end + end + + context 'that is a user namespace' do + let_it_be(:user) { create(:user) } + let_it_be(:namespace) { user.namespace } + + it_behaves_like example_name + end + end + + describe '#execute' do + shared_examples 'finding packages by name' do + it { is_expected.to eq([package]) } + + context 'with unknown package name' do + let(:package_name) { 'baz' } + + it { is_expected.to be_empty } + end + end + + subject { finder.execute } + + context 'with a project' do + let(:finder) { described_class.new(package_name, project: project) } - it { is_expected.to eq([package]) } + it_behaves_like 'finding packages by name' - context 'with unknown package name' do - let(:package_name) { 'baz' } + context 'set to nil' do + let(:project) { nil } - it { is_expected.to be_empty } + it { is_expected.to be_empty } + end end - context 'with nil project' do - let(:project) { nil } + context 'with a namespace' do + let(:finder) { described_class.new(package_name, namespace: namespace) } + + it_behaves_like 'accepting a namespace for', 'finding packages by name' + + context 'set to nil' do + let_it_be(:namespace) { nil } - it { is_expected.to be_empty } + it { is_expected.to be_empty } + end end end describe '#find_by_version' do let(:version) { package.version } - subject { described_class.new(project, package.name).find_by_version(version) } + subject { finder.find_by_version(version) } + + shared_examples 'finding packages by version' do + it { is_expected.to eq(package) } + + context 'with unknown version' do + let(:version) { 'foobar' } + + it { is_expected.to be_nil } + end + end + + context 'with a project' do + let(:finder) { described_class.new(package_name, project: project) } + + it_behaves_like 'finding packages by version' + end + + context 'with a namespace' do + let(:finder) { described_class.new(package_name, namespace: namespace) } + + it_behaves_like 'accepting a namespace for', 'finding packages by version' + end + end + + describe '#last' do + subject { finder.last } + + shared_examples 'finding package by last' do + it { is_expected.to eq(package) } + end + + context 'with a project' do + let(:finder) { described_class.new(package_name, project: project) } + + it_behaves_like 'finding package by last' + end + + context 'with a namespace' do + let(:finder) { described_class.new(package_name, namespace: namespace) } + + it_behaves_like 'accepting a namespace for', 'finding package by last' - it { is_expected.to eq(package) } + context 'with duplicate packages' do + let_it_be(:namespace) { create(:group) } + let_it_be(:subgroup1) { create(:group, parent: namespace) } + let_it_be(:subgroup2) { create(:group, parent: namespace) } + let_it_be(:project2) { create(:project, namespace: subgroup2) } + let_it_be(:package2) { create(:npm_package, name: package.name, project: project2) } - context 'with unknown version' do - let(:version) { 'foobar' } + before do + project.update!(namespace: subgroup1) + end - it { is_expected.to be_nil } + # the most recent one is returned + it { is_expected.to eq(package2) } + end end end end diff --git a/spec/finders/packages/package_finder_spec.rb b/spec/finders/packages/package_finder_spec.rb index ef07e7575d1..e8c7404a612 100644 --- a/spec/finders/packages/package_finder_spec.rb +++ b/spec/finders/packages/package_finder_spec.rb @@ -14,7 +14,7 @@ RSpec.describe ::Packages::PackageFinder do it { is_expected.to eq(maven_package) } context 'processing packages' do - let_it_be(:nuget_package) { create(:nuget_package, project: project, name: Packages::Nuget::CreatePackageService::TEMPORARY_PACKAGE_NAME) } + let_it_be(:nuget_package) { create(:nuget_package, project: project, name: Packages::Nuget::TEMPORARY_PACKAGE_NAME) } let(:package_id) { nuget_package.id } it 'are not returned' do diff --git a/spec/finders/packages/packages_finder_spec.rb b/spec/finders/packages/packages_finder_spec.rb index 6e92616bafa..0add77a8478 100644 --- a/spec/finders/packages/packages_finder_spec.rb +++ b/spec/finders/packages/packages_finder_spec.rb @@ -76,7 +76,7 @@ RSpec.describe ::Packages::PackagesFinder do end context 'with processing packages' do - let_it_be(:nuget_package) { create(:nuget_package, project: project, name: Packages::Nuget::CreatePackageService::TEMPORARY_PACKAGE_NAME) } + let_it_be(:nuget_package) { create(:nuget_package, project: project, name: Packages::Nuget::TEMPORARY_PACKAGE_NAME) } it { is_expected.to match_array([conan_package, maven_package]) } end diff --git a/spec/finders/projects/groups_finder_spec.rb b/spec/finders/projects/groups_finder_spec.rb new file mode 100644 index 00000000000..89d4edaec7c --- /dev/null +++ b/spec/finders/projects/groups_finder_spec.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Projects::GroupsFinder do + describe '#execute' do + let_it_be(:user) { create(:user) } + let_it_be(:root_group) { create(:group, :public) } + let_it_be(:project_group) { create(:group, :public, parent: root_group) } + let_it_be(:shared_group_with_dev_access) { create(:group, :private, parent: root_group) } + let_it_be(:shared_group_with_reporter_access) { create(:group, :private) } + + let_it_be(:public_project) { create(:project, :public, group: project_group) } + let_it_be(:private_project) { create(:project, :private, group: project_group) } + + before_all do + [public_project, private_project].each do |project| + create(:project_group_link, :developer, group: shared_group_with_dev_access, project: project) + create(:project_group_link, :reporter, group: shared_group_with_reporter_access, project: project) + end + end + + let(:params) { {} } + let(:current_user) { user } + let(:finder) { described_class.new(project: project, current_user: current_user, params: params) } + + subject { finder.execute } + + shared_examples 'finding related groups' do + it 'returns ancestor groups for this project' do + is_expected.to match_array([project_group, root_group]) + end + + context 'when the project does not belong to any group' do + before do + allow(project).to receive(:group) { nil } + end + + it { is_expected.to eq([]) } + end + + context 'when shared groups option is on' do + let(:params) { { with_shared: true } } + + it 'returns ancestor and all shared groups' do + is_expected.to match_array([project_group, root_group, shared_group_with_dev_access, shared_group_with_reporter_access]) + end + + context 'when shared_min_access_level is developer' do + let(:params) { super().merge(shared_min_access_level: Gitlab::Access::DEVELOPER) } + + it 'returns ancestor and shared groups with at least developer access' do + is_expected.to match_array([project_group, root_group, shared_group_with_dev_access]) + end + end + end + + context 'when skip group option is on' do + let(:params) { { skip_groups: [project_group.id] } } + + it 'excludes provided groups' do + is_expected.to match_array([root_group]) + end + end + end + + context 'Public project' do + it_behaves_like 'finding related groups' do + let(:project) { public_project } + + context 'when user is not authorized' do + let(:current_user) { nil } + + it 'returns ancestor groups for this project' do + is_expected.to match_array([project_group, root_group]) + end + end + end + end + + context 'Private project' do + it_behaves_like 'finding related groups' do + let(:project) { private_project } + + before do + project.add_developer(user) + end + + context 'when user is not authorized' do + let(:current_user) { nil } + + it { is_expected.to eq([]) } + end + end + end + + context 'Missing project' do + let(:project) { nil } + + it { is_expected.to eq([]) } + end + end +end diff --git a/spec/finders/repositories/changelog_commits_finder_spec.rb b/spec/finders/repositories/changelog_commits_finder_spec.rb new file mode 100644 index 00000000000..8665d36144a --- /dev/null +++ b/spec/finders/repositories/changelog_commits_finder_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Repositories::ChangelogCommitsFinder do + let_it_be(:project) { create(:project, :repository) } + + describe '#each_page' do + it 'only yields commits with the given trailer' do + finder = described_class.new( + project: project, + from: '570e7b2abdd848b95f2f578043fc23bd6f6fd24d', + to: 'c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd' + ) + + commits = finder.each_page('Signed-off-by').to_a.flatten + + expect(commits.length).to eq(1) + expect(commits.first.id).to eq('5937ac0a7beb003549fc5fd26fc247adbce4a52e') + expect(commits.first.trailers).to eq( + 'Signed-off-by' => 'Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>' + ) + end + + it 'ignores commits that are reverted' do + # This range of commits is found on the branch + # https://gitlab.com/gitlab-org/gitlab-test/-/commits/trailers. + finder = described_class.new( + project: project, + from: 'ddd0f15ae83993f5cb66a927a28673882e99100b', + to: '694e6c2f08cad00d183682d9dede99615998a630' + ) + + commits = finder.each_page('Changelog').to_a.flatten + + expect(commits).to be_empty + end + + it 'includes revert commits if they have a trailer' do + finder = described_class.new( + project: project, + from: 'ddd0f15ae83993f5cb66a927a28673882e99100b', + to: 'f0a5ed60d24c98ec6d00ac010c1f3f01ee0a8373' + ) + + initial_commit = project.commit('ed2e92bf50b3da2c7cbbab053f4977a4ecbd109a') + revert_commit = project.commit('f0a5ed60d24c98ec6d00ac010c1f3f01ee0a8373') + + commits = finder.each_page('Changelog').to_a.flatten + + expect(commits).to eq([revert_commit, initial_commit]) + end + + it 'supports paginating of commits' do + finder = described_class.new( + project: project, + from: 'c1acaa58bbcbc3eafe538cb8274ba387047b69f8', + to: '5937ac0a7beb003549fc5fd26fc247adbce4a52e', + per_page: 1 + ) + + commits = finder.each_page('Signed-off-by') + + expect(commits.count).to eq(4) + end + end + + describe '#revert_commit_sha' do + let(:finder) { described_class.new(project: project, from: 'a', to: 'b') } + + it 'returns the SHA of a reverted commit' do + commit = double( + :commit, + description: 'This reverts commit 152c03af1b09f50fa4b567501032b106a3a81ff3.' + ) + + expect(finder.send(:revert_commit_sha, commit)) + .to eq('152c03af1b09f50fa4b567501032b106a3a81ff3') + end + + it 'returns nil when the commit is not a revert commit' do + commit = double(:commit, description: 'foo') + + expect(finder.send(:revert_commit_sha, commit)).to be_nil + end + + it 'returns nil when the commit has no description' do + commit = double(:commit, description: nil) + + expect(finder.send(:revert_commit_sha, commit)).to be_nil + end + end +end diff --git a/spec/finders/repositories/commits_with_trailer_finder_spec.rb b/spec/finders/repositories/commits_with_trailer_finder_spec.rb deleted file mode 100644 index 0c457aae340..00000000000 --- a/spec/finders/repositories/commits_with_trailer_finder_spec.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Repositories::CommitsWithTrailerFinder do - let(:project) { create(:project, :repository) } - - describe '#each_page' do - it 'only yields commits with the given trailer' do - finder = described_class.new( - project: project, - from: '570e7b2abdd848b95f2f578043fc23bd6f6fd24d', - to: 'c7fbe50c7c7419d9701eebe64b1fdacc3df5b9dd' - ) - - commits = finder.each_page('Signed-off-by').to_a.flatten - - expect(commits.length).to eq(1) - expect(commits.first.id).to eq('5937ac0a7beb003549fc5fd26fc247adbce4a52e') - expect(commits.first.trailers).to eq( - 'Signed-off-by' => 'Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>' - ) - end - - it 'supports paginating of commits' do - finder = described_class.new( - project: project, - from: 'c1acaa58bbcbc3eafe538cb8274ba387047b69f8', - to: '5937ac0a7beb003549fc5fd26fc247adbce4a52e', - per_page: 1 - ) - - commits = finder.each_page('Signed-off-by') - - expect(commits.count).to eq(4) - end - end -end diff --git a/spec/finders/repositories/previous_tag_finder_spec.rb b/spec/finders/repositories/previous_tag_finder_spec.rb index 7cc33d11baf..b332dd158d1 100644 --- a/spec/finders/repositories/previous_tag_finder_spec.rb +++ b/spec/finders/repositories/previous_tag_finder_spec.rb @@ -12,16 +12,20 @@ RSpec.describe Repositories::PreviousTagFinder do tag1 = double(:tag1, name: 'v1.0.0') tag2 = double(:tag2, name: 'v1.1.0') tag3 = double(:tag3, name: 'v2.0.0') - tag4 = double(:tag4, name: '1.0.0') + tag4 = double(:tag4, name: '0.9.0') + tag5 = double(:tag5, name: 'v0.8.0-pre1') + tag6 = double(:tag6, name: 'v0.7.0') allow(project.repository) .to receive(:tags) - .and_return([tag1, tag3, tag2, tag4]) + .and_return([tag1, tag3, tag2, tag4, tag5, tag6]) expect(finder.execute('2.1.0')).to eq(tag3) expect(finder.execute('2.0.0')).to eq(tag2) expect(finder.execute('1.5.0')).to eq(tag2) expect(finder.execute('1.0.1')).to eq(tag1) + expect(finder.execute('1.0.0')).to eq(tag4) + expect(finder.execute('0.9.0')).to eq(tag6) end end diff --git a/spec/finders/security/license_compliance_jobs_finder_spec.rb b/spec/finders/security/license_compliance_jobs_finder_spec.rb index 3066912df12..de4a7eb2c12 100644 --- a/spec/finders/security/license_compliance_jobs_finder_spec.rb +++ b/spec/finders/security/license_compliance_jobs_finder_spec.rb @@ -15,10 +15,9 @@ RSpec.describe Security::LicenseComplianceJobsFinder do let!(:container_scanning_build) { create(:ci_build, :container_scanning, pipeline: pipeline) } let!(:dast_build) { create(:ci_build, :dast, pipeline: pipeline) } let!(:license_scanning_build) { create(:ci_build, :license_scanning, pipeline: pipeline) } - let!(:license_management_build) { create(:ci_build, :license_management, pipeline: pipeline) } - it 'returns only the license_scanning jobs' do - is_expected.to contain_exactly(license_scanning_build, license_management_build) + it 'returns only the license_scanning job' do + is_expected.to contain_exactly(license_scanning_build) end end end diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb index d9cc71106d5..b0f8b803141 100644 --- a/spec/finders/users_finder_spec.rb +++ b/spec/finders/users_finder_spec.rb @@ -12,7 +12,7 @@ RSpec.describe UsersFinder do it 'returns all users' do users = described_class.new(user).execute - expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user, admin_user) + expect(users).to contain_exactly(user, normal_user, blocked_user, external_user, omniauth_user, internal_user, admin_user) end it 'filters by username' do @@ -48,12 +48,18 @@ RSpec.describe UsersFinder do it 'filters by active users' do users = described_class.new(user, active: true).execute - expect(users).to contain_exactly(user, normal_user, omniauth_user, admin_user) + expect(users).to contain_exactly(user, normal_user, external_user, omniauth_user, admin_user) end - it 'returns no external users' do + it 'filters by external users' do users = described_class.new(user, external: true).execute + expect(users).to contain_exactly(external_user) + end + + it 'filters by non external users' do + users = described_class.new(user, non_external: true).execute + expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user, admin_user) end @@ -71,7 +77,7 @@ RSpec.describe UsersFinder do it 'filters by non internal users' do users = described_class.new(user, non_internal: true).execute - expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, admin_user) + expect(users).to contain_exactly(user, normal_user, external_user, blocked_user, omniauth_user, admin_user) end it 'does not filter by custom attributes' do @@ -80,18 +86,18 @@ RSpec.describe UsersFinder do custom_attributes: { foo: 'bar' } ).execute - expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user, admin_user) + expect(users).to contain_exactly(user, normal_user, blocked_user, external_user, omniauth_user, internal_user, admin_user) end it 'orders returned results' do users = described_class.new(user, sort: 'id_asc').execute - expect(users).to eq([normal_user, admin_user, blocked_user, omniauth_user, internal_user, user]) + expect(users).to eq([normal_user, admin_user, blocked_user, external_user, omniauth_user, internal_user, user]) end it 'does not filter by admins' do users = described_class.new(user, admins: true).execute - expect(users).to contain_exactly(user, normal_user, admin_user, blocked_user, omniauth_user, internal_user) + expect(users).to contain_exactly(user, normal_user, external_user, admin_user, blocked_user, omniauth_user, internal_user) end end |