summaryrefslogtreecommitdiff
path: root/spec/finders
diff options
context:
space:
mode:
Diffstat (limited to 'spec/finders')
-rw-r--r--spec/finders/admin/projects_finder_spec.rb4
-rw-r--r--spec/finders/alert_management/alerts_finder_spec.rb42
-rw-r--r--spec/finders/autocomplete/move_to_project_finder_spec.rb10
-rw-r--r--spec/finders/ci/daily_build_group_report_results_finder_spec.rb2
-rw-r--r--spec/finders/ci/pipelines_for_merge_request_finder_spec.rb2
-rw-r--r--spec/finders/design_management/designs_finder_spec.rb30
-rw-r--r--spec/finders/fork_targets_finder_spec.rb4
-rw-r--r--spec/finders/group_descendants_finder_spec.rb2
-rw-r--r--spec/finders/group_projects_finder_spec.rb6
-rw-r--r--spec/finders/issues_finder_spec.rb58
-rw-r--r--spec/finders/joined_groups_finder_spec.rb2
-rw-r--r--spec/finders/members_finder_spec.rb25
-rw-r--r--spec/finders/merge_requests_finder_spec.rb102
-rw-r--r--spec/finders/milestones_finder_spec.rb8
-rw-r--r--spec/finders/personal_access_tokens_finder_spec.rb42
-rw-r--r--spec/finders/personal_projects_finder_spec.rb2
-rw-r--r--spec/finders/projects_finder_spec.rb8
-rw-r--r--spec/finders/releases_finder_spec.rb195
-rw-r--r--spec/finders/template_finder_spec.rb4
-rw-r--r--spec/finders/todos_finder_spec.rb54
-rw-r--r--spec/finders/uploader_finder_spec.rb4
21 files changed, 478 insertions, 128 deletions
diff --git a/spec/finders/admin/projects_finder_spec.rb b/spec/finders/admin/projects_finder_spec.rb
index 03eb41ddfb6..8522170874f 100644
--- a/spec/finders/admin/projects_finder_spec.rb
+++ b/spec/finders/admin/projects_finder_spec.rb
@@ -88,7 +88,7 @@ RSpec.describe Admin::ProjectsFinder do
context 'filter by abandoned' do
before do
- private_project.update(last_activity_at: Time.zone.now - 6.months - 1.minute)
+ private_project.update!(last_activity_at: Time.zone.now - 6.months - 1.minute)
end
let(:params) { { abandoned: true } }
@@ -98,7 +98,7 @@ RSpec.describe Admin::ProjectsFinder do
context 'filter by last_repository_check_failed' do
before do
- private_project.update(last_repository_check_failed: true)
+ private_project.update!(last_repository_check_failed: true)
end
let(:params) { { last_repository_check_failed: true } }
diff --git a/spec/finders/alert_management/alerts_finder_spec.rb b/spec/finders/alert_management/alerts_finder_spec.rb
index 7bf9047704b..926446b31d5 100644
--- a/spec/finders/alert_management/alerts_finder_spec.rb
+++ b/spec/finders/alert_management/alerts_finder_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
RSpec.describe AlertManagement::AlertsFinder, '#execute' do
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project) }
- let_it_be(:alert_1) { create(:alert_management_alert, :all_fields, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) }
- let_it_be(:alert_2) { create(:alert_management_alert, :all_fields, :ignored, project: project, events: 1, severity: :critical) }
- let_it_be(:alert_3) { create(:alert_management_alert, :all_fields) }
+ let_it_be(:resolved_alert) { create(:alert_management_alert, :all_fields, :resolved, project: project, ended_at: 1.year.ago, events: 2, severity: :high) }
+ let_it_be(:ignored_alert) { create(:alert_management_alert, :all_fields, :ignored, project: project, events: 1, severity: :critical) }
+ let_it_be(:triggered_alert) { create(:alert_management_alert, :all_fields) }
let(:params) { {} }
describe '#execute' do
@@ -23,13 +23,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
end
context 'empty params' do
- it { is_expected.to contain_exactly(alert_1, alert_2) }
+ it { is_expected.to contain_exactly(resolved_alert, ignored_alert) }
end
context 'iid given' do
- let(:params) { { iid: alert_1.iid } }
+ let(:params) { { iid: resolved_alert.iid } }
- it { is_expected.to match_array(alert_1) }
+ it { is_expected.to match_array(resolved_alert) }
context 'unknown iid' do
let(:params) { { iid: 'unknown' } }
@@ -41,13 +41,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
context 'status given' do
let(:params) { { status: AlertManagement::Alert::STATUSES[:resolved] } }
- it { is_expected.to match_array(alert_1) }
+ it { is_expected.to match_array(resolved_alert) }
context 'with an array of statuses' do
- let(:alert_3) { create(:alert_management_alert) }
+ let(:triggered_alert) { create(:alert_management_alert) }
let(:params) { { status: [AlertManagement::Alert::STATUSES[:resolved]] } }
- it { is_expected.to match_array(alert_1) }
+ it { is_expected.to match_array(resolved_alert) }
end
context 'with no alerts of status' do
@@ -59,13 +59,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
context 'with an empty status array' do
let(:params) { { status: [] } }
- it { is_expected.to match_array([alert_1, alert_2]) }
+ it { is_expected.to match_array([resolved_alert, ignored_alert]) }
end
context 'with an nil status' do
let(:params) { { status: nil } }
- it { is_expected.to match_array([alert_1, alert_2]) }
+ it { is_expected.to match_array([resolved_alert, ignored_alert]) }
end
end
@@ -74,13 +74,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
context 'sorts alerts ascending' do
let(:params) { { sort: 'created_asc' } }
- it { is_expected.to eq [alert_1, alert_2] }
+ it { is_expected.to eq [resolved_alert, ignored_alert] }
end
context 'sorts alerts descending' do
let(:params) { { sort: 'created_desc' } }
- it { is_expected.to eq [alert_2, alert_1] }
+ it { is_expected.to eq [ignored_alert, resolved_alert] }
end
end
@@ -88,13 +88,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
context 'sorts alerts ascending' do
let(:params) { { sort: 'updated_asc' } }
- it { is_expected.to eq [alert_1, alert_2] }
+ it { is_expected.to eq [resolved_alert, ignored_alert] }
end
context 'sorts alerts descending' do
let(:params) { { sort: 'updated_desc' } }
- it { is_expected.to eq [alert_2, alert_1] }
+ it { is_expected.to eq [ignored_alert, resolved_alert] }
end
end
@@ -102,13 +102,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
context 'sorts alerts ascending' do
let(:params) { { sort: 'started_at_asc' } }
- it { is_expected.to eq [alert_1, alert_2] }
+ it { is_expected.to eq [resolved_alert, ignored_alert] }
end
context 'sorts alerts descending' do
let(:params) { { sort: 'started_at_desc' } }
- it { is_expected.to eq [alert_2, alert_1] }
+ it { is_expected.to eq [ignored_alert, resolved_alert] }
end
end
@@ -116,13 +116,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
context 'sorts alerts ascending' do
let(:params) { { sort: 'ended_at_asc' } }
- it { is_expected.to eq [alert_1, alert_2] }
+ it { is_expected.to eq [resolved_alert, ignored_alert] }
end
context 'sorts alerts descending' do
let(:params) { { sort: 'ended_at_desc' } }
- it { is_expected.to eq [alert_2, alert_1] }
+ it { is_expected.to eq [ignored_alert, resolved_alert] }
end
end
@@ -133,13 +133,13 @@ RSpec.describe AlertManagement::AlertsFinder, '#execute' do
context 'sorts alerts ascending' do
let(:params) { { sort: 'event_count_asc' } }
- it { is_expected.to eq [alert_2, alert_1, alert_count_3, alert_count_6] }
+ it { is_expected.to eq [ignored_alert, resolved_alert, alert_count_3, alert_count_6] }
end
context 'sorts alerts descending' do
let(:params) { { sort: 'event_count_desc' } }
- it { is_expected.to eq [alert_count_6, alert_count_3, alert_1, alert_2] }
+ it { is_expected.to eq [alert_count_6, alert_count_3, resolved_alert, ignored_alert] }
end
end
diff --git a/spec/finders/autocomplete/move_to_project_finder_spec.rb b/spec/finders/autocomplete/move_to_project_finder_spec.rb
index 61328a5335a..fb2de908777 100644
--- a/spec/finders/autocomplete/move_to_project_finder_spec.rb
+++ b/spec/finders/autocomplete/move_to_project_finder_spec.rb
@@ -22,14 +22,14 @@ RSpec.describe Autocomplete::MoveToProjectFinder do
expect(finder.execute).to be_empty
end
- it 'returns projects equal or above Gitlab::Access::REPORTER ordered by name' do
+ it 'returns projects equal or above Gitlab::Access::REPORTER' do
reporter_project.add_reporter(user)
developer_project.add_developer(user)
maintainer_project.add_maintainer(user)
finder = described_class.new(user, project_id: project.id)
- expect(finder.execute.to_a).to eq([reporter_project, developer_project, maintainer_project])
+ expect(finder.execute.to_a).to contain_exactly(reporter_project, developer_project, maintainer_project)
end
it 'does not include the source project' do
@@ -53,7 +53,7 @@ RSpec.describe Autocomplete::MoveToProjectFinder do
it 'does not return projects for which issues are disabled' do
reporter_project.add_reporter(user)
- reporter_project.update(issues_enabled: false)
+ reporter_project.update!(issues_enabled: false)
other_reporter_project = create(:project)
other_reporter_project.add_reporter(user)
@@ -88,10 +88,10 @@ RSpec.describe Autocomplete::MoveToProjectFinder do
wadus_project.add_maintainer(user)
expect(described_class.new(user, project_id: project.id).execute.to_a)
- .to eq([foo_project, wadus_project])
+ .to contain_exactly(foo_project, wadus_project)
expect(described_class.new(user, project_id: project.id, search: 'wadus').execute.to_a)
- .to eq([wadus_project])
+ .to contain_exactly(wadus_project)
end
it 'allows searching by parent namespace' do
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 bdb0bc9b561..c0434b5f371 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
@@ -59,6 +59,8 @@ RSpec.describe Ci::DailyBuildGroupReportResultsFinder do
end
end
+ private
+
def create_daily_coverage(group_name, coverage, date)
create(
:ci_daily_build_group_report_result,
diff --git a/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb b/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb
index ca6e0793d55..196fde5efe0 100644
--- a/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb
+++ b/spec/finders/ci/pipelines_for_merge_request_finder_spec.rb
@@ -115,7 +115,7 @@ RSpec.describe Ci::PipelinesForMergeRequestFinder do
context 'with multiple irrelevant merge_request_diffs' do
before do
- merge_request.update(target_branch: 'v1.0.0')
+ merge_request.update!(target_branch: 'v1.0.0')
end
it_behaves_like 'returning pipelines with proper ordering'
diff --git a/spec/finders/design_management/designs_finder_spec.rb b/spec/finders/design_management/designs_finder_spec.rb
index 696327cc49c..0133095827d 100644
--- a/spec/finders/design_management/designs_finder_spec.rb
+++ b/spec/finders/design_management/designs_finder_spec.rb
@@ -8,9 +8,9 @@ RSpec.describe DesignManagement::DesignsFinder do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:issue) { create(:issue, project: project) }
- let_it_be(:design1) { create(:design, :with_file, issue: issue, versions_count: 1) }
- let_it_be(:design2) { create(:design, :with_file, issue: issue, versions_count: 1) }
- let_it_be(:design3) { create(:design, :with_file, issue: issue, versions_count: 1) }
+ let_it_be(:design1) { create(:design, :with_file, issue: issue, versions_count: 1, relative_position: 3) }
+ let_it_be(:design2) { create(:design, :with_file, issue: issue, versions_count: 1, relative_position: 2) }
+ let_it_be(:design3) { create(:design, :with_file, issue: issue, versions_count: 1, relative_position: 1) }
let(:params) { {} }
subject(:designs) { described_class.new(issue, user, params).execute }
@@ -38,8 +38,28 @@ RSpec.describe DesignManagement::DesignsFinder do
enable_design_management
end
- it 'returns the designs' do
- is_expected.to contain_exactly(design1, design2, design3)
+ it 'returns the designs sorted by their relative position' do
+ is_expected.to eq([design3, design2, design1])
+ end
+
+ context 'when the :reorder_designs feature is enabled for the project' do
+ before do
+ stub_feature_flags(reorder_designs: project)
+ end
+
+ it 'returns the designs sorted by their relative position' do
+ is_expected.to eq([design3, design2, design1])
+ end
+ end
+
+ context 'when the :reorder_designs feature is disabled' do
+ before do
+ stub_feature_flags(reorder_designs: false)
+ end
+
+ it 'returns the designs sorted by ID' do
+ is_expected.to eq([design1, design2, design3])
+ end
end
context 'when argument is the ids of designs' do
diff --git a/spec/finders/fork_targets_finder_spec.rb b/spec/finders/fork_targets_finder_spec.rb
index 3c66f4e5757..7208f46cfff 100644
--- a/spec/finders/fork_targets_finder_spec.rb
+++ b/spec/finders/fork_targets_finder_spec.rb
@@ -10,15 +10,19 @@ RSpec.describe ForkTargetsFinder do
let!(:maintained_group) do
create(:group).tap { |g| g.add_maintainer(user) }
end
+
let!(:owned_group) do
create(:group).tap { |g| g.add_owner(user) }
end
+
let!(:developer_group) do
create(:group).tap { |g| g.add_developer(user) }
end
+
let!(:reporter_group) do
create(:group).tap { |g| g.add_reporter(user) }
end
+
let!(:guest_group) do
create(:group).tap { |g| g.add_guest(user) }
end
diff --git a/spec/finders/group_descendants_finder_spec.rb b/spec/finders/group_descendants_finder_spec.rb
index 77ef546e083..2f9303606b1 100644
--- a/spec/finders/group_descendants_finder_spec.rb
+++ b/spec/finders/group_descendants_finder_spec.rb
@@ -122,7 +122,7 @@ RSpec.describe GroupDescendantsFinder do
it 'does not include projects shared with the group' do
project = create(:project, namespace: group)
other_project = create(:project)
- other_project.project_group_links.create(group: group,
+ other_project.project_group_links.create!(group: group,
group_access: Gitlab::Access::MAINTAINER)
expect(finder.execute).to contain_exactly(project)
diff --git a/spec/finders/group_projects_finder_spec.rb b/spec/finders/group_projects_finder_spec.rb
index 14f2bb017c6..c66fdb19260 100644
--- a/spec/finders/group_projects_finder_spec.rb
+++ b/spec/finders/group_projects_finder_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe GroupProjectsFinder do
let!(:shared_project_4) { create(:project, :internal, path: '8') }
before do
- shared_project_4.project_group_links.create(group_access: Gitlab::Access::REPORTER, group: group)
+ shared_project_4.project_group_links.create!(group_access: Gitlab::Access::REPORTER, group: group)
end
let(:params) { { min_access_level: Gitlab::Access::MAINTAINER } }
@@ -76,7 +76,7 @@ RSpec.describe GroupProjectsFinder do
context "with external user" do
before do
- current_user.update(external: true)
+ current_user.update!(external: true)
end
it { is_expected.to match_array([shared_project_2, shared_project_1]) }
@@ -107,7 +107,7 @@ RSpec.describe GroupProjectsFinder do
context "with external user" do
before do
- current_user.update(external: true)
+ current_user.update!(external: true)
end
context 'with subgroups projects' do
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index 672318c292e..fb7d4e808fe 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -185,9 +185,9 @@ RSpec.describe IssuesFinder do
let(:params) { { milestone_title: group_milestone.title } }
before do
- project2.update(namespace: group)
- issue2.update(milestone: group_milestone)
- issue3.update(milestone: group_milestone)
+ project2.update!(namespace: group)
+ issue2.update!(milestone: group_milestone)
+ issue3.update!(milestone: group_milestone)
end
it 'returns issues assigned to that group milestone' do
@@ -668,6 +668,58 @@ RSpec.describe IssuesFinder do
end
end
+ context 'filtering by issue type' do
+ let_it_be(:incident_issue) { create(:incident, project: project1) }
+
+ context 'no type given' do
+ let(:params) { { issue_types: [] } }
+
+ it 'returns all issues' do
+ expect(issues).to contain_exactly(incident_issue, issue1, issue2, issue3, issue4)
+ end
+ end
+
+ context 'incident type' do
+ let(:params) { { issue_types: ['incident'] } }
+
+ it 'returns incident issues' do
+ expect(issues).to contain_exactly(incident_issue)
+ end
+ end
+
+ context 'issue type' do
+ let(:params) { { issue_types: ['issue'] } }
+
+ it 'returns all issues with type issue' do
+ expect(issues).to contain_exactly(issue1, issue2, issue3, issue4)
+ end
+ end
+
+ context 'multiple params' do
+ let(:params) { { issue_types: %w(issue incident) } }
+
+ it 'returns all issues' do
+ expect(issues).to contain_exactly(incident_issue, issue1, issue2, issue3, issue4)
+ end
+ end
+
+ context 'without array' do
+ let(:params) { { issue_types: 'incident' } }
+
+ it 'returns incident issues' do
+ expect(issues).to contain_exactly(incident_issue)
+ end
+ end
+
+ context 'invalid params' do
+ let(:params) { { issue_types: ['nonsense'] } }
+
+ it 'returns no issues' do
+ expect(issues).to eq(Issue.none)
+ end
+ end
+ end
+
context 'when the user is unauthorized' do
let(:search_user) { nil }
diff --git a/spec/finders/joined_groups_finder_spec.rb b/spec/finders/joined_groups_finder_spec.rb
index 8f826ef67ec..058db735708 100644
--- a/spec/finders/joined_groups_finder_spec.rb
+++ b/spec/finders/joined_groups_finder_spec.rb
@@ -55,7 +55,7 @@ RSpec.describe JoinedGroupsFinder do
context 'external users' do
before do
- profile_visitor.update(external: true)
+ profile_visitor.update!(external: true)
end
context 'if not a member' do
diff --git a/spec/finders/members_finder_spec.rb b/spec/finders/members_finder_spec.rb
index b14ad84a96e..3ef8d6a01aa 100644
--- a/spec/finders/members_finder_spec.rb
+++ b/spec/finders/members_finder_spec.rb
@@ -10,16 +10,39 @@ RSpec.describe MembersFinder, '#execute' do
let_it_be(:user2) { create(:user) }
let_it_be(:user3) { create(:user) }
let_it_be(:user4) { create(:user) }
+ let_it_be(:blocked_user) { create(:user, :blocked) }
it 'returns members for project and parent groups' do
nested_group.request_access(user1)
member1 = group.add_maintainer(user2)
member2 = nested_group.add_maintainer(user3)
member3 = project.add_maintainer(user4)
+ blocked_member = project.add_maintainer(blocked_user)
result = described_class.new(project, user2).execute
- expect(result).to contain_exactly(member1, member2, member3)
+ expect(result).to contain_exactly(member1, member2, member3, blocked_member)
+ end
+
+ it 'returns owners and maintainers' do
+ member1 = group.add_owner(user1)
+ group.add_developer(user2)
+ member3 = project.add_maintainer(user3)
+ project.add_developer(user4)
+
+ result = described_class.new(project, user2, params: { owners_and_maintainers: true }).execute
+
+ expect(result).to contain_exactly(member1, member3)
+ end
+
+ it 'returns active users and excludes invited users' do
+ member1 = project.add_maintainer(user2)
+ create(:project_member, :invited, project: project, invite_email: create(:user).email)
+ project.add_maintainer(blocked_user)
+
+ result = described_class.new(project, user2, params: { active_without_invites_and_requests: true }).execute
+
+ expect(result).to contain_exactly(member1)
end
it 'includes only non-invite members if user do not have amdin permissions on project' do
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index e3643698012..5b86c891e47 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -85,6 +85,31 @@ RSpec.describe MergeRequestsFinder do
expect(merge_requests).to contain_exactly(merge_request5)
end
+ context 'filters by merged_at date' do
+ before do
+ merge_request1.metrics.update!(merged_at: 5.days.ago)
+ merge_request2.metrics.update!(merged_at: 10.days.ago)
+ end
+
+ describe 'merged_after' do
+ subject { described_class.new(user, merged_after: 6.days.ago).execute }
+
+ it { is_expected.to eq([merge_request1]) }
+ end
+
+ describe 'merged_before' do
+ subject { described_class.new(user, merged_before: 6.days.ago).execute }
+
+ it { is_expected.to eq([merge_request2]) }
+ end
+
+ describe 'when both merged_after and merged_before is given' do
+ subject { described_class.new(user, merged_after: 15.days.ago, merged_before: 6.days.ago).execute }
+
+ it { is_expected.to eq([merge_request2]) }
+ end
+ end
+
context 'filtering by group' do
it 'includes all merge requests when user has access excluding merge requests from projects the user does not have access to' do
private_project = allow_gitaly_n_plus_1 { create(:project, :private, group: group) }
@@ -192,43 +217,59 @@ RSpec.describe MergeRequestsFinder do
expect(merge_requests).to contain_exactly(merge_request3)
end
- describe 'WIP state' do
+ describe 'draft state' do
let!(:wip_merge_request1) { create(:merge_request, :simple, author: user, source_project: project5, target_project: project5, title: 'WIP: thing') }
let!(:wip_merge_request2) { create(:merge_request, :simple, author: user, source_project: project6, target_project: project6, title: 'wip thing') }
let!(:wip_merge_request3) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project1, title: '[wip] thing') }
let!(:wip_merge_request4) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2, title: 'wip: thing') }
+ let!(:draft_merge_request1) { create(:merge_request, :simple, author: user, source_branch: 'draft1', source_project: project5, target_project: project5, title: 'Draft: thing') }
+ let!(:draft_merge_request2) { create(:merge_request, :simple, author: user, source_branch: 'draft2', source_project: project6, target_project: project6, title: '[draft] thing') }
+ let!(:draft_merge_request3) { create(:merge_request, :simple, author: user, source_branch: 'draft3', source_project: project1, target_project: project1, title: '(draft) thing') }
+ let!(:draft_merge_request4) { create(:merge_request, :simple, author: user, source_branch: 'draft4', source_project: project1, target_project: project2, title: 'Draft - thing') }
- it 'filters by wip' do
- params = { wip: 'yes' }
+ [:wip, :draft].each do |draft_param_key|
+ it "filters by #{draft_param_key}" do
+ params = { draft_param_key => 'yes' }
- merge_requests = described_class.new(user, params).execute
+ merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to contain_exactly(merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4)
- end
+ expect(merge_requests).to contain_exactly(
+ merge_request4, merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4,
+ draft_merge_request1, draft_merge_request2, draft_merge_request3, draft_merge_request4
+ )
+ end
- it 'filters by not wip' do
- params = { wip: 'no' }
+ 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, params).execute
+ merge_requests = described_class.new(user, { draft_param_key => 'yes' }).execute
- expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3)
- end
+ 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 'returns all items if no valid wip param exists' do
- params = { wip: '' }
+ it "filters by not #{draft_param_key}" do
+ params = { draft_param_key => 'no' }
- merge_requests = described_class.new(user, params).execute
+ merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to contain_exactly(
- merge_request1, merge_request2, merge_request3, merge_request4,
- merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3,
- wip_merge_request4)
- end
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3)
+ end
- it 'adds wip to scalar params' do
- scalar_params = described_class.scalar_params
+ it "returns all items if no valid #{draft_param_key} param exists" do
+ params = { draft_param_key => '' }
+
+ merge_requests = described_class.new(user, params).execute
- expect(scalar_params).to include(:wip, :assignee_id)
+ expect(merge_requests).to contain_exactly(
+ merge_request1, merge_request2, merge_request3, merge_request4,
+ merge_request5, wip_merge_request1, wip_merge_request2, wip_merge_request3, wip_merge_request4,
+ draft_merge_request1, draft_merge_request2, draft_merge_request3, draft_merge_request4
+ )
+ end
end
context 'filter by deployment' do
@@ -265,6 +306,14 @@ RSpec.describe MergeRequestsFinder do
end
end
+ describe '.scalar_params' do
+ it 'contains scalar params related to merge requests' do
+ scalar_params = described_class.scalar_params
+
+ expect(scalar_params).to include(:wip, :draft, :assignee_id)
+ end
+ end
+
context 'assignee filtering' do
let(:issuables) { described_class.new(user, params).execute }
@@ -311,9 +360,8 @@ RSpec.describe MergeRequestsFinder do
let(:group_milestone) { create(:milestone, group: group) }
before do
- project2.update(namespace: group)
- merge_request2.update(milestone: group_milestone)
- merge_request3.update(milestone: group_milestone)
+ merge_request1.update!(milestone: group_milestone)
+ merge_request2.update!(milestone: group_milestone)
end
it 'returns merge requests assigned to that group milestone' do
@@ -321,7 +369,7 @@ RSpec.describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to contain_exactly(merge_request2, merge_request3)
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request2)
end
context 'using NOT' do
@@ -330,7 +378,7 @@ RSpec.describe MergeRequestsFinder do
it 'returns MRs not assigned to that group milestone' do
merge_requests = described_class.new(user, params).execute
- expect(merge_requests).to contain_exactly(merge_request1, merge_request4, merge_request5)
+ expect(merge_requests).to contain_exactly(merge_request3, merge_request4, merge_request5)
end
end
end
diff --git a/spec/finders/milestones_finder_spec.rb b/spec/finders/milestones_finder_spec.rb
index 5920c185c64..6e486671132 100644
--- a/spec/finders/milestones_finder_spec.rb
+++ b/spec/finders/milestones_finder_spec.rb
@@ -56,6 +56,14 @@ RSpec.describe MilestonesFinder do
milestone_3.close
end
+ it 'filters by id' do
+ params[:ids] = [milestone_1.id, milestone_2.id]
+
+ result = described_class.new(params).execute
+
+ expect(result).to contain_exactly(milestone_1, milestone_2)
+ end
+
it 'filters by active state' do
params[:state] = 'active'
result = described_class.new(params).execute
diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb
index 94954f4153b..c8913329839 100644
--- a/spec/finders/personal_access_tokens_finder_spec.rb
+++ b/spec/finders/personal_access_tokens_finder_spec.rb
@@ -3,13 +3,14 @@
require 'spec_helper'
RSpec.describe PersonalAccessTokensFinder do
- def finder(options = {})
- described_class.new(options)
+ def finder(options = {}, current_user = nil)
+ described_class.new(options, current_user)
end
describe '#execute' do
let(:user) { create(:user) }
let(:params) { {} }
+ let(:current_user) { nil }
let!(:active_personal_access_token) { create(:personal_access_token, user: user) }
let!(:expired_personal_access_token) { create(:personal_access_token, :expired, user: user) }
let!(:revoked_personal_access_token) { create(:personal_access_token, :revoked, user: user) }
@@ -17,7 +18,42 @@ RSpec.describe PersonalAccessTokensFinder do
let!(:expired_impersonation_token) { create(:personal_access_token, :expired, :impersonation, user: user) }
let!(:revoked_impersonation_token) { create(:personal_access_token, :revoked, :impersonation, user: user) }
- subject { finder(params).execute }
+ subject { finder(params, current_user).execute }
+
+ context 'when current_user is defined' do
+ let(:current_user) { create(:admin) }
+ let(:params) { { user: user } }
+
+ context 'current_user is allowed to read PATs' do
+ it do
+ is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token,
+ revoked_personal_access_token, expired_personal_access_token,
+ revoked_impersonation_token, expired_impersonation_token)
+ end
+ end
+
+ context 'current_user is not allowed to read PATs' do
+ let(:current_user) { create(:user) }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'when user param is not set' do
+ let(:params) { {} }
+
+ it do
+ is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token,
+ revoked_personal_access_token, expired_personal_access_token,
+ revoked_impersonation_token, expired_impersonation_token)
+ end
+
+ context 'when current_user is not an administrator' do
+ let(:current_user) { create(:user) }
+
+ it { is_expected.to be_empty }
+ end
+ end
+ end
describe 'without user' do
it do
diff --git a/spec/finders/personal_projects_finder_spec.rb b/spec/finders/personal_projects_finder_spec.rb
index 62e9999fdd6..493ec0e569e 100644
--- a/spec/finders/personal_projects_finder_spec.rb
+++ b/spec/finders/personal_projects_finder_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe PersonalProjectsFinder do
context 'external' do
before do
- current_user.update(external: true)
+ current_user.update!(external: true)
end
it { is_expected.to eq([public_project, private_project]) }
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index bd71a8186ad..29b6dc61386 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -244,8 +244,8 @@ RSpec.describe ProjectsFinder, :do_not_mock_admin_mode do
let(:params) { { last_activity_after: 60.minutes.ago } }
before do
- internal_project.update(last_activity_at: Time.now)
- public_project.update(last_activity_at: 61.minutes.ago)
+ internal_project.update!(last_activity_at: Time.now)
+ public_project.update!(last_activity_at: 61.minutes.ago)
end
it { is_expected.to match_array([internal_project]) }
@@ -255,8 +255,8 @@ RSpec.describe ProjectsFinder, :do_not_mock_admin_mode do
let(:params) { { last_activity_before: 60.minutes.ago } }
before do
- internal_project.update(last_activity_at: Time.now)
- public_project.update(last_activity_at: 61.minutes.ago)
+ internal_project.update!(last_activity_at: Time.now)
+ public_project.update!(last_activity_at: 61.minutes.ago)
end
it { is_expected.to match_array([public_project]) }
diff --git a/spec/finders/releases_finder_spec.rb b/spec/finders/releases_finder_spec.rb
index 3dc01570d64..e8049a9eb81 100644
--- a/spec/finders/releases_finder_spec.rb
+++ b/spec/finders/releases_finder_spec.rb
@@ -3,29 +3,68 @@
require 'spec_helper'
RSpec.describe ReleasesFinder do
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository) }
- let(:params) { {} }
+ let(:user) { create(:user) }
+ let(:group) { create :group }
+ let(:project) { create(:project, :repository, group: group) }
+ let(:params) { {} }
+ let(:args) { {} }
let(:repository) { project.repository }
let(:v1_0_0) { create(:release, project: project, tag: 'v1.0.0') }
let(:v1_1_0) { create(:release, project: project, tag: 'v1.1.0') }
- let(:finder) { described_class.new(project, user, params) }
before do
v1_0_0.update_attribute(:released_at, 2.days.ago)
v1_1_0.update_attribute(:released_at, 1.day.ago)
end
- describe '#execute' do
- subject { finder.execute(**args) }
+ shared_examples_for 'when the user is not part of the project' do
+ it 'returns no releases' do
+ is_expected.to be_empty
+ end
+ end
+
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27716
+ shared_examples_for 'when tag is nil' do
+ before do
+ v1_0_0.update_column(:tag, nil)
+ end
+
+ it 'ignores rows with a nil tag' do
+ expect(subject.size).to eq(1)
+ expect(subject).to eq([v1_1_0])
+ end
+ end
+
+ shared_examples_for 'when a tag parameter is passed' do
+ let(:params) { { tag: 'v1.0.0' } }
+
+ it 'only returns the release with the matching tag' do
+ expect(subject).to eq([v1_0_0])
+ end
+ end
+
+ shared_examples_for 'preload' do
+ it 'preloads associations' do
+ expect(Release).to receive(:preloaded).once.and_call_original
+
+ subject
+ end
+
+ context 'when preload is false' do
+ let(:args) { { preload: false } }
- let(:args) { {} }
+ it 'does not preload associations' do
+ expect(Release).not_to receive(:preloaded)
- context 'when the user is not part of the project' do
- it 'returns no releases' do
- is_expected.to be_empty
+ subject
end
end
+ end
+
+ describe 'when parent is a project' do
+ subject { described_class.new(project, user, params).execute(**args) }
+
+ it_behaves_like 'when the user is not part of the project'
context 'when the user is a project developer' do
before do
@@ -38,39 +77,137 @@ RSpec.describe ReleasesFinder do
expect(subject).to eq([v1_1_0, v1_0_0])
end
- it 'preloads associations' do
- expect(Release).to receive(:preloaded).once.and_call_original
+ it_behaves_like 'preload'
+ it_behaves_like 'when tag is nil'
+ it_behaves_like 'when a tag parameter is passed'
+ end
+ end
- subject
- end
+ describe 'when parent is a group' do
+ context 'without subgroups' do
+ let(:project2) { create(:project, :repository, namespace: group) }
+ let!(:v6) { create(:release, project: project2, tag: 'v6') }
- context 'when preload is false' do
- let(:args) { { preload: false } }
+ subject { described_class.new(group, user, params).execute(**args) }
- it 'does not preload associations' do
- expect(Release).not_to receive(:preloaded)
+ it_behaves_like 'when the user is not part of the project'
+
+ context 'when the user is a project developer on one sibling project' do
+ before do
+ project.add_developer(user)
+ v1_0_0.update_attribute(:released_at, 3.days.ago)
+ v1_1_0.update_attribute(:released_at, 1.day.ago)
+ end
- subject
+ it 'sorts by release date' do
+ expect(subject.size).to eq(2)
+ expect(subject).to eq([v1_1_0, v1_0_0])
end
end
- # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27716
- context 'when tag is nil' do
+ context 'when the user is a project developer on all projects' do
before do
- v1_0_0.update_column(:tag, nil)
+ project.add_developer(user)
+ project2.add_developer(user)
+ v1_0_0.update_attribute(:released_at, 3.days.ago)
+ v6.update_attribute(:released_at, 2.days.ago)
+ v1_1_0.update_attribute(:released_at, 1.day.ago)
end
- it 'ignores rows with a nil tag' do
- expect(subject.size).to eq(1)
- expect(subject).to eq([v1_1_0])
+ it 'sorts by release date' do
+ expect(subject.size).to eq(3)
+ expect(subject).to eq([v1_1_0, v6, v1_0_0])
+ end
+
+ it_behaves_like 'when a tag parameter is passed'
+ end
+ end
+
+ describe 'with subgroups' do
+ let(:params) { { include_subgroups: true } }
+
+ subject { described_class.new(group, user, params).execute(**args) }
+
+ context 'with a single-level subgroup' do
+ let(:subgroup) { create :group, parent: group }
+ let(:project2) { create(:project, :repository, namespace: subgroup) }
+ let!(:v6) { create(:release, project: project2, tag: 'v6') }
+
+ it_behaves_like 'when the user is not part of the project'
+
+ context 'when the user a project developer in the subgroup project' do
+ before do
+ project2.add_developer(user)
+ end
+
+ it 'returns only the subgroup releases' do
+ expect(subject).to match_array([v6])
+ end
+ end
+
+ context 'when the user a project developer in both projects' do
+ before do
+ project.add_developer(user)
+ project2.add_developer(user)
+ v6.update_attribute(:released_at, 2.days.ago)
+ end
+
+ it 'returns all releases' do
+ expect(subject).to match_array([v1_1_0, v1_0_0, v6])
+ end
+
+ it_behaves_like 'when a tag parameter is passed'
end
end
- context 'when a tag parameter is passed' do
- let(:params) { { tag: 'v1.0.0' } }
+ context 'with a multi-level subgroup' do
+ let(:subgroup) { create :group, parent: group }
+ let(:subsubgroup) { create :group, parent: subgroup }
+ let(:project2) { create(:project, :repository, namespace: subgroup) }
+ let(:project3) { create(:project, :repository, namespace: subsubgroup) }
+ let!(:v6) { create(:release, project: project2, tag: 'v6') }
+ let!(:p3) { create(:release, project: project3, tag: 'p3') }
+
+ before do
+ v6.update_attribute(:released_at, 2.days.ago)
+ p3.update_attribute(:released_at, 3.days.ago)
+ end
+
+ it_behaves_like 'when the user is not part of the project'
+
+ context 'when the user a project developer in the subgroup and subsubgroup project' do
+ before do
+ project2.add_developer(user)
+ project3.add_developer(user)
+ end
+
+ it 'returns only the subgroup and subsubgroup releases' do
+ expect(subject).to match_array([v6, p3])
+ end
+ end
+
+ context 'when the user a project developer in the subsubgroup project' do
+ before do
+ project3.add_developer(user)
+ end
+
+ it 'returns only the subsubgroup releases' do
+ expect(subject).to match_array([p3])
+ end
+ end
+
+ context 'when the user a project developer in all projects' do
+ before do
+ project.add_developer(user)
+ project2.add_developer(user)
+ project3.add_developer(user)
+ end
+
+ it 'returns all releases' do
+ expect(subject).to match_array([v1_1_0, v6, v1_0_0, p3])
+ end
- it 'only returns the release with the matching tag' do
- expect(subject).to eq([v1_0_0])
+ it_behaves_like 'when a tag parameter is passed'
end
end
end
diff --git a/spec/finders/template_finder_spec.rb b/spec/finders/template_finder_spec.rb
index 34f81e249e2..0fdd6ab402d 100644
--- a/spec/finders/template_finder_spec.rb
+++ b/spec/finders/template_finder_spec.rb
@@ -12,7 +12,8 @@ RSpec.describe TemplateFinder do
:dockerfiles | described_class
:gitignores | described_class
:gitlab_ci_ymls | described_class
- :licenses | ::LicenseTemplateFinder
+ :licenses | ::LicenseTemplateFinder
+ :metrics_dashboard_ymls | described_class
end
with_them do
@@ -28,6 +29,7 @@ RSpec.describe TemplateFinder do
:dockerfiles | 'Binary'
:gitignores | 'Actionscript'
:gitlab_ci_ymls | 'Android'
+ :metrics_dashboard_ymls | 'Default'
end
with_them do
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index f6796398782..577ad80ede1 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -4,14 +4,14 @@ require 'spec_helper'
RSpec.describe TodosFinder do
describe '#execute' do
- let(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:project) { create(:project, namespace: group) }
- let(:issue) { create(:issue, project: project) }
- let(:merge_request) { create(:merge_request, source_project: project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, :repository, namespace: group) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:merge_request) { create(:merge_request, source_project: project) }
let(:finder) { described_class }
- before do
+ before_all do
group.add_developer(user)
end
@@ -89,8 +89,6 @@ RSpec.describe TodosFinder do
end
it 'raises an argument error when invalid type is passed' do
- create(:todo, user: user, group: group, target: create(:design))
-
todos_finder = finder.new(user, { type: %w[Issue MergeRequest NotAValidType] })
expect { todos_finder.execute }.to raise_error(ArgumentError)
@@ -131,8 +129,8 @@ RSpec.describe TodosFinder do
end
context 'when filtering by author' do
- let(:author1) { create(:user) }
- let(:author2) { create(:user) }
+ let_it_be(:author1) { create(:user) }
+ let_it_be(:author2) { create(:user) }
let!(:todo1) { create(:todo, user: user, author: author1) }
let!(:todo2) { create(:todo, user: user, author: author2) }
@@ -154,7 +152,7 @@ RSpec.describe TodosFinder do
context 'by groups' do
context 'with subgroups' do
- let(:subgroup) { create(:group, parent: group) }
+ let_it_be(:subgroup) { create(:group, parent: group) }
let!(:todo3) { create(:todo, user: user, group: subgroup, target: issue) }
it 'returns todos from subgroups when filtered by a group' do
@@ -167,17 +165,14 @@ RSpec.describe TodosFinder do
context 'filtering for multiple groups' do
let_it_be(:group2) { create(:group) }
let_it_be(:group3) { create(:group) }
+ let_it_be(:subgroup1) { create(:group, parent: group) }
+ let_it_be(:subgroup2) { create(:group, parent: group2) }
let!(:todo1) { create(:todo, user: user, project: project, target: issue) }
let!(:todo2) { create(:todo, user: user, group: group, target: merge_request) }
let!(:todo3) { create(:todo, user: user, group: group2, target: merge_request) }
-
- let(:subgroup1) { create(:group, parent: group) }
let!(:todo4) { create(:todo, user: user, group: subgroup1, target: issue) }
-
- let(:subgroup2) { create(:group, parent: group2) }
let!(:todo5) { create(:todo, user: user, group: subgroup2, target: issue) }
-
let!(:todo6) { create(:todo, user: user, group: group3, target: issue) }
it 'returns the expected groups' do
@@ -232,6 +227,29 @@ RSpec.describe TodosFinder do
expect(todos).to match_array([todo2, todo1])
end
end
+
+ context 'when filtering by target id' do
+ it 'returns the expected todos for the target' do
+ todos = finder.new(user, { type: 'Issue', target_id: issue.id }).execute
+
+ expect(todos).to match_array([todo1])
+ end
+
+ it 'returns the expected todos for multiple target ids' do
+ another_issue = create(:issue, project: project)
+ todo3 = create(:todo, user: user, project: project, target: another_issue)
+
+ todos = finder.new(user, { type: 'Issue', target_id: [issue.id, another_issue.id] }).execute
+
+ expect(todos).to match_array([todo1, todo3])
+ end
+
+ it 'returns the expected todos for empty target id collection' do
+ todos = finder.new(user, { target_id: [] }).execute
+
+ expect(todos).to match_array([todo1, todo2])
+ end
+ end
end
context 'external authorization' do
@@ -307,9 +325,9 @@ RSpec.describe TodosFinder do
it 'returns the expected types' do
expected_result =
if Gitlab.ee?
- %w[Epic Issue MergeRequest DesignManagement::Design]
+ %w[Epic Issue MergeRequest DesignManagement::Design AlertManagement::Alert]
else
- %w[Issue MergeRequest DesignManagement::Design]
+ %w[Issue MergeRequest DesignManagement::Design AlertManagement::Alert]
end
expect(described_class.todo_types).to contain_exactly(*expected_result)
diff --git a/spec/finders/uploader_finder_spec.rb b/spec/finders/uploader_finder_spec.rb
index 814d4b88b57..e1488f18d8a 100644
--- a/spec/finders/uploader_finder_spec.rb
+++ b/spec/finders/uploader_finder_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe UploaderFinder do
subject { described_class.new(project, secret, file_name).execute }
before do
- upload.save
+ upload.save!
end
context 'when successful' do
@@ -32,7 +32,7 @@ RSpec.describe UploaderFinder do
context 'when path traversal in file name' do
before do
upload.path = '/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd)'
- upload.save
+ upload.save!
end
it 'returns nil' do