Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-20 17:22:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-20 17:22:11 +0300
commit0c872e02b2c822e3397515ec324051ff540f0cd5 (patch)
treece2fb6ce7030e4dad0f4118d21ab6453e5938cdd /spec/finders
parentf7e05a6853b12f02911494c4b3fe53d9540d74fc (diff)
Add latest changes from gitlab-org/gitlab@15-7-stable-eev15.7.0-rc42
Diffstat (limited to 'spec/finders')
-rw-r--r--spec/finders/autocomplete/routes_finder_spec.rb40
-rw-r--r--spec/finders/branches_finder_spec.rb63
-rw-r--r--spec/finders/ci/auth_job_finder_spec.rb4
-rw-r--r--spec/finders/ci/freeze_periods_finder_spec.rb (renamed from spec/finders/freeze_periods_finder_spec.rb)2
-rw-r--r--spec/finders/ci/jobs_finder_spec.rb88
-rw-r--r--spec/finders/ci/pipelines_finder_spec.rb41
-rw-r--r--spec/finders/ci/runners_finder_spec.rb447
-rw-r--r--spec/finders/clusters/agent_tokens_finder_spec.rb53
-rw-r--r--spec/finders/environments/environments_finder_spec.rb24
-rw-r--r--spec/finders/issues_finder_spec.rb2
-rw-r--r--spec/finders/notes_finder_spec.rb10
-rw-r--r--spec/finders/personal_access_tokens_finder_spec.rb475
-rw-r--r--spec/finders/projects_finder_spec.rb17
-rw-r--r--spec/finders/tags_finder_spec.rb13
-rw-r--r--spec/finders/todos_finder_spec.rb4
-rw-r--r--spec/finders/users_finder_spec.rb52
-rw-r--r--spec/finders/work_items/work_items_finder_spec.rb2
17 files changed, 857 insertions, 480 deletions
diff --git a/spec/finders/autocomplete/routes_finder_spec.rb b/spec/finders/autocomplete/routes_finder_spec.rb
index c5b040a5640..f37e8e8de7b 100644
--- a/spec/finders/autocomplete/routes_finder_spec.rb
+++ b/spec/finders/autocomplete/routes_finder_spec.rb
@@ -32,8 +32,24 @@ RSpec.describe Autocomplete::RoutesFinder do
context 'when user is admin' do
let(:current_user) { admin }
- it 'finds all namespaces matching the search excluding project namespaces' do
- is_expected.to match_array([group.route, group2.route, user_route])
+ context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do
+ it 'finds all namespaces matching the search excluding project namespaces' do
+ is_expected.to match_array([group.route, group2.route, user_route])
+ end
+ end
+
+ context 'when admin mode setting is enabled' do
+ context 'when in admin mode', :enable_admin_mode do
+ it 'finds all namespaces matching the search excluding project namespaces' do
+ is_expected.to match_array([group.route, group2.route, user_route])
+ end
+ end
+
+ context 'when not in admin mode' do
+ it 'does not find all namespaces' do
+ is_expected.to match_array([])
+ end
+ end
end
end
end
@@ -48,8 +64,24 @@ RSpec.describe Autocomplete::RoutesFinder do
context 'when user is admin' do
let(:current_user) { admin }
- it 'finds all projects matching the search' do
- is_expected.to match_array([project.route, project2.route])
+ context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do
+ it 'finds all projects matching the search' do
+ is_expected.to match_array([project.route, project2.route])
+ end
+ end
+
+ context 'when admin mode setting is enabled' do
+ context 'when in admin mode', :enable_admin_mode do
+ it 'finds all projects matching the search' do
+ is_expected.to match_array([project.route, project2.route])
+ end
+ end
+
+ context 'when not in admin mode' do
+ it 'does not find all projects' do
+ is_expected.to match_array([])
+ end
+ end
end
end
end
diff --git a/spec/finders/branches_finder_spec.rb b/spec/finders/branches_finder_spec.rb
index f14c60c4b8f..18f8d1adecc 100644
--- a/spec/finders/branches_finder_spec.rb
+++ b/spec/finders/branches_finder_spec.rb
@@ -72,16 +72,6 @@ RSpec.describe BranchesFinder do
end
end
- context 'with an unknown name' do
- let(:params) { { search: 'random' } }
-
- it 'does not find any branch' do
- result = subject
-
- expect(result.count).to eq(0)
- end
- end
-
context 'by provided names' do
let(:params) { { names: %w[fix csv lfs does-not-exist] } }
@@ -115,6 +105,49 @@ RSpec.describe BranchesFinder do
end
end
+ context 'by name with wildcard' do
+ let(:params) { { search: 'f*e' } }
+
+ it 'filters branches' do
+ result = subject
+
+ expect(result.first.name).to eq('2-mb-file')
+ expect(result.count).to eq(30)
+ end
+ end
+
+ context 'by mixed regex operators' do
+ let(:params) { { search: '^f*e$' } }
+
+ it 'filters branches' do
+ result = subject
+
+ expect(result.first.name).to eq('feature')
+ expect(result.count).to eq(1)
+ end
+ end
+
+ context 'by name with multiple wildcards' do
+ let(:params) { { search: 'f*a*e' } }
+
+ it 'filters branches' do
+ result = subject
+
+ expect(result.first.name).to eq('after-create-delete-modify-move')
+ expect(result.count).to eq(11)
+ end
+ end
+
+ context 'with an unknown name' do
+ let(:params) { { search: 'random' } }
+
+ it 'does not find any branch' do
+ result = subject
+
+ expect(result.count).to eq(0)
+ end
+ end
+
context 'by nonexistent name that begins with' do
let(:params) { { search: '^nope' } }
@@ -134,6 +167,16 @@ RSpec.describe BranchesFinder do
expect(result.count).to eq(0)
end
end
+
+ context 'by nonexistent name with wildcard' do
+ let(:params) { { search: 'zz*asdf' } }
+
+ it 'filters branches' do
+ result = subject
+
+ expect(result.count).to eq(0)
+ end
+ end
end
context 'filter and sort' do
diff --git a/spec/finders/ci/auth_job_finder_spec.rb b/spec/finders/ci/auth_job_finder_spec.rb
index 0a326699875..73a65d0c5af 100644
--- a/spec/finders/ci/auth_job_finder_spec.rb
+++ b/spec/finders/ci/auth_job_finder_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe Ci::AuthJobFinder do
+RSpec.describe Ci::AuthJobFinder, feature_category: :continuous_integration do
let_it_be(:user, reload: true) { create(:user) }
let_it_be(:job, reload: true) { create(:ci_build, status: :running, user: user) }
@@ -68,7 +68,7 @@ RSpec.describe Ci::AuthJobFinder do
it 'sets ci_job_token_scope on the job user', :aggregate_failures do
expect(subject).to eq(job)
expect(subject.user).to be_from_ci_job_token
- expect(subject.user.ci_job_token_scope.source_project).to eq(job.project)
+ expect(subject.user.ci_job_token_scope.current_project).to eq(job.project)
end
end
end
diff --git a/spec/finders/freeze_periods_finder_spec.rb b/spec/finders/ci/freeze_periods_finder_spec.rb
index 53cc07d91b0..6c58028a221 100644
--- a/spec/finders/freeze_periods_finder_spec.rb
+++ b/spec/finders/ci/freeze_periods_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe FreezePeriodsFinder do
+RSpec.describe Ci::FreezePeriodsFinder, feature_category: :release_orchestration do
subject(:finder) { described_class.new(project, user).execute }
let(:project) { create(:project, :private) }
diff --git a/spec/finders/ci/jobs_finder_spec.rb b/spec/finders/ci/jobs_finder_spec.rb
index dd3ba9721e4..0b3777a2fe8 100644
--- a/spec/finders/ci/jobs_finder_spec.rb
+++ b/spec/finders/ci/jobs_finder_spec.rb
@@ -14,52 +14,55 @@ RSpec.describe Ci::JobsFinder, '#execute' do
let(:params) { {} }
context 'no project' do
- subject { described_class.new(current_user: admin, params: params).execute }
+ subject { described_class.new(current_user: current_user, params: params).execute }
- it 'returns all jobs' do
- expect(subject).to match_array([pending_job, running_job, successful_job])
- end
+ context 'with admin' do
+ let(:current_user) { admin }
- context 'non admin user' do
- let(:admin) { user }
+ context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do
+ it { is_expected.to match_array([pending_job, running_job, successful_job]) }
+ end
- it 'returns no jobs' do
- expect(subject).to be_empty
+ context 'when admin mode setting is enabled' do
+ context 'when in admin mode', :enable_admin_mode do
+ it { is_expected.to match_array([pending_job, running_job, successful_job]) }
+ end
+
+ context 'when not in admin mode' do
+ it { is_expected.to be_empty }
+ end
end
end
+ context 'with normal user' do
+ let(:current_user) { user }
+
+ it { is_expected.to be_empty }
+ end
+
context 'without user' do
- let(:admin) { nil }
+ let(:current_user) { nil }
- it 'returns no jobs' do
- expect(subject).to be_empty
- end
+ it { is_expected.to be_empty }
end
- context 'scope is present' do
+ context 'with scope', :enable_admin_mode do
+ let(:current_user) { admin }
let(:jobs) { [pending_job, running_job, successful_job] }
- where(:scope, :index) do
- [
- ['pending', 0],
- ['running', 1],
- ['finished', 2]
- ]
+ using RSpec::Parameterized::TableSyntax
+
+ where(:scope, :expected_jobs) do
+ 'pending' | lazy { [pending_job] }
+ 'running' | lazy { [running_job] }
+ 'finished' | lazy { [successful_job] }
+ %w[running success] | lazy { [running_job, successful_job] }
end
with_them do
let(:params) { { scope: scope } }
- it { expect(subject).to match_array([jobs[index]]) }
- end
- end
-
- context 'scope is an array' do
- let(:jobs) { [pending_job, running_job, successful_job, canceled_job] }
- let(:params) { { scope: %w'running success' } }
-
- it 'filters by the job statuses in the scope' do
- expect(subject).to contain_exactly(running_job, successful_job)
+ it { is_expected.to match_array(expected_jobs) }
end
end
end
@@ -96,6 +99,33 @@ RSpec.describe Ci::JobsFinder, '#execute' do
end
end
+ context 'when artifacts are present for some jobs' do
+ let_it_be(:job_with_artifacts) { create(:ci_build, :success, pipeline: pipeline, name: 'test') }
+ let_it_be(:artifact) { create(:ci_job_artifact, job: job_with_artifacts) }
+
+ subject { described_class.new(current_user: user, project: project, params: params).execute }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when with_artifacts is true' do
+ let(:params) { { with_artifacts: true } }
+
+ it 'returns only jobs with artifacts' do
+ expect(subject).to match_array([job_with_artifacts])
+ end
+ end
+
+ context 'when with_artifacts is false' do
+ let(:params) { { with_artifacts: false } }
+
+ it 'returns all jobs' do
+ expect(subject).to match_array([successful_job, job_with_artifacts])
+ end
+ end
+ end
+
context 'when pipeline is present' do
before_all do
project.add_maintainer(user)
diff --git a/spec/finders/ci/pipelines_finder_spec.rb b/spec/finders/ci/pipelines_finder_spec.rb
index 908210e0296..a2e8fe8df5a 100644
--- a/spec/finders/ci/pipelines_finder_spec.rb
+++ b/spec/finders/ci/pipelines_finder_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Ci::PipelinesFinder do
- let(:project) { create(:project, :public, :repository) }
+ let_it_be(:project) { create(:project, :public, :repository) }
let(:current_user) { nil }
let(:params) { {} }
@@ -242,6 +242,45 @@ RSpec.describe Ci::PipelinesFinder do
end
end
+ context 'when name is specified' do
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project, name: 'Build pipeline') }
+ let_it_be(:pipeline_other) { create(:ci_pipeline, project: project, name: 'Some other pipeline') }
+
+ let(:params) { { name: 'build Pipeline' } }
+
+ it 'performs case insensitive compare' do
+ is_expected.to contain_exactly(pipeline)
+ end
+
+ context 'when name does not exist' do
+ let(:params) { { name: 'absent-name' } }
+
+ it 'returns empty' do
+ is_expected.to be_empty
+ end
+ end
+
+ context 'when pipeline_name feature flag is off' do
+ before do
+ stub_feature_flags(pipeline_name: false)
+ end
+
+ it 'ignores name parameter' do
+ is_expected.to contain_exactly(pipeline, pipeline_other)
+ end
+ end
+
+ context 'when pipeline_name_search feature flag is off' do
+ before do
+ stub_feature_flags(pipeline_name_search: false)
+ end
+
+ it 'ignores name parameter' do
+ is_expected.to contain_exactly(pipeline, pipeline_other)
+ 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 18eecd0f073..a8ef99eeaec 100644
--- a/spec/finders/ci/runners_finder_spec.rb
+++ b/spec/finders/ci/runners_finder_spec.rb
@@ -7,219 +7,221 @@ RSpec.describe Ci::RunnersFinder do
let_it_be(:admin) { create(:user, :admin) }
describe '#execute' do
- context 'with 2 runners' do
- let_it_be(:runner1) { create(:ci_runner, active: true) }
- let_it_be(:runner2) { create(:ci_runner, active: false) }
-
- context 'with empty params' do
- it 'returns all runners' do
- expect(Ci::Runner).to receive(:with_tags).and_call_original
- expect(described_class.new(current_user: admin, params: {}).execute).to match_array [runner1, runner2]
+ shared_examples 'executes as admin' do
+ context 'with 2 runners' do
+ let_it_be(:runner1) { create(:ci_runner, active: true) }
+ let_it_be(:runner2) { create(:ci_runner, active: false) }
+
+ context 'with empty params' do
+ it 'returns all runners' do
+ expect(Ci::Runner).to receive(:with_tags).and_call_original
+ expect(described_class.new(current_user: admin, params: {}).execute).to match_array [runner1, runner2]
+ end
end
- end
- context 'with nil group' do
- it 'returns all runners' do
- expect(Ci::Runner).to receive(:with_tags).and_call_original
- expect(described_class.new(current_user: admin, params: { group: nil }).execute).to match_array [runner1, runner2]
+ context 'with nil group' do
+ it 'returns all runners' do
+ expect(Ci::Runner).to receive(:with_tags).and_call_original
+ expect(described_class.new(current_user: admin, params: { group: nil }).execute).to match_array [runner1, runner2]
+ end
end
- end
- context 'with preload param set to :tag_name true' do
- it 'requests tags' do
- expect(Ci::Runner).to receive(:with_tags).and_call_original
- expect(described_class.new(current_user: admin, params: { preload: { tag_name: true } }).execute).to match_array [runner1, runner2]
+ context 'with preload param set to :tag_name true' do
+ it 'requests tags' do
+ expect(Ci::Runner).to receive(:with_tags).and_call_original
+ expect(described_class.new(current_user: admin, params: { preload: { tag_name: true } }).execute).to match_array [runner1, runner2]
+ end
end
- end
- context 'with preload param set to :tag_name false' do
- it 'does not request tags' do
- expect(Ci::Runner).not_to receive(:with_tags)
- expect(described_class.new(current_user: admin, params: { preload: { tag_name: false } }).execute).to match_array [runner1, runner2]
+ context 'with preload param set to :tag_name false' do
+ it 'does not request tags' do
+ expect(Ci::Runner).not_to receive(:with_tags)
+ expect(described_class.new(current_user: admin, params: { preload: { tag_name: false } }).execute).to match_array [runner1, runner2]
+ end
end
end
- end
- 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
+ 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 'by upgrade status' do
- let(:upgrade_status) {}
+ context 'by upgrade status' do
+ let(:upgrade_status) {}
- let_it_be(:runner1) { create(:ci_runner, version: 'a') }
- let_it_be(:runner2) { create(:ci_runner, version: 'b') }
- let_it_be(:runner3) { create(:ci_runner, version: 'c') }
- let_it_be(:runner_version_recommended) do
- create(:ci_runner_version, version: 'a', status: :recommended)
- end
+ let_it_be(:runner1) { create(:ci_runner, version: 'a') }
+ let_it_be(:runner2) { create(:ci_runner, version: 'b') }
+ let_it_be(:runner3) { create(:ci_runner, version: 'c') }
+ let_it_be(:runner_version_recommended) do
+ create(:ci_runner_version, version: 'a', status: :recommended)
+ end
- let_it_be(:runner_version_not_available) do
- create(:ci_runner_version, version: 'b', status: :not_available)
- end
+ let_it_be(:runner_version_not_available) do
+ create(:ci_runner_version, version: 'b', status: :not_available)
+ end
- let_it_be(:runner_version_available) do
- create(:ci_runner_version, version: 'c', status: :available)
- end
+ let_it_be(:runner_version_available) do
+ create(:ci_runner_version, version: 'c', status: :available)
+ end
- def execute
- described_class.new(current_user: admin, params: { upgrade_status: upgrade_status }).execute
- end
+ def execute
+ described_class.new(current_user: admin, params: { upgrade_status: upgrade_status }).execute
+ end
- Ci::RunnerVersion.statuses.keys.map(&:to_sym).each do |status|
- context "set to :#{status}" do
- let(:upgrade_status) { status }
+ Ci::RunnerVersion.statuses.keys.map(&:to_sym).each do |status|
+ context "set to :#{status}" do
+ let(:upgrade_status) { status }
- it "calls with_upgrade_status scope with corresponding :#{status} status" do
- if [:available, :not_available, :recommended].include?(status)
- expected_result = Ci::Runner.with_upgrade_status(status)
- end
+ it "calls with_upgrade_status scope with corresponding :#{status} status" do
+ if [:available, :not_available, :recommended].include?(status)
+ expected_result = Ci::Runner.with_upgrade_status(status)
+ end
- expect(Ci::Runner).to receive(:with_upgrade_status).with(status).and_call_original
+ expect(Ci::Runner).to receive(:with_upgrade_status).with(status).and_call_original
- result = execute
+ result = execute
- expect(result).to match_array(expected_result) if expected_result
+ expect(result).to match_array(expected_result) if expected_result
+ end
end
end
- end
- context 'set to an invalid value' do
- let(:upgrade_status) { :some_invalid_status }
+ context 'set to an invalid value' do
+ let(:upgrade_status) { :some_invalid_status }
- it 'raises ArgumentError' do
- expect { execute }.to raise_error(ArgumentError)
+ it 'raises ArgumentError' do
+ expect { execute }.to raise_error(ArgumentError)
+ end
end
- end
- context 'set to nil' do
- let(:upgrade_status) { nil }
+ context 'set to nil' do
+ let(:upgrade_status) { nil }
- it 'does not call with_upgrade_status' do
- expect(Ci::Runner).not_to receive(:with_upgrade_status)
+ it 'does not call with_upgrade_status' do
+ expect(Ci::Runner).not_to receive(:with_upgrade_status)
- expect(execute).to match_array(Ci::Runner.all)
+ expect(execute).to match_array(Ci::Runner.all)
+ end
end
end
- end
- 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
+ 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 'by active status' do
- it 'with active set as false calls the corresponding scope on Ci::Runner with false' do
- expect(Ci::Runner).to receive(:active).with(false).and_call_original
+ context 'by active status' do
+ it 'with active set as false calls the corresponding scope on Ci::Runner with false' do
+ expect(Ci::Runner).to receive(:active).with(false).and_call_original
- described_class.new(current_user: admin, params: { active: false }).execute
- end
+ described_class.new(current_user: admin, params: { active: false }).execute
+ end
- it 'with active set as true calls the corresponding scope on Ci::Runner with true' do
- expect(Ci::Runner).to receive(:active).with(true).and_call_original
+ it 'with active set as true calls the corresponding scope on Ci::Runner with true' do
+ expect(Ci::Runner).to receive(:active).with(true).and_call_original
- described_class.new(current_user: admin, params: { active: true }).execute
+ described_class.new(current_user: admin, params: { active: true }).execute
+ end
end
- end
- context '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 '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
- end
- context 'sorting' do
- let_it_be(:runner1) { create :ci_runner, created_at: '2018-07-12 07:00', contacted_at: 1.minute.ago, token_expires_at: '2022-02-15 07:00' }
- let_it_be(:runner2) { create :ci_runner, created_at: '2018-07-12 08:00', contacted_at: 3.minutes.ago, token_expires_at: '2022-02-15 06:00' }
- let_it_be(:runner3) { create :ci_runner, created_at: '2018-07-12 09:00', contacted_at: 2.minutes.ago }
+ context 'sorting' do
+ let_it_be(:runner1) { create :ci_runner, created_at: '2018-07-12 07:00', contacted_at: 1.minute.ago, token_expires_at: '2022-02-15 07:00' }
+ let_it_be(:runner2) { create :ci_runner, created_at: '2018-07-12 08:00', contacted_at: 3.minutes.ago, token_expires_at: '2022-02-15 06:00' }
+ let_it_be(:runner3) { create :ci_runner, created_at: '2018-07-12 09:00', contacted_at: 2.minutes.ago }
- subject do
- described_class.new(current_user: admin, params: params).execute
- end
+ subject do
+ described_class.new(current_user: admin, params: params).execute
+ end
- shared_examples 'sorts by created_at descending' do
- it 'sorts by created_at descending' do
- is_expected.to eq [runner3, runner2, runner1]
+ shared_examples 'sorts by created_at descending' do
+ it 'sorts by created_at descending' do
+ is_expected.to eq [runner3, runner2, runner1]
+ end
end
- end
- context 'without sort param' do
- let(:params) { {} }
+ context 'without sort param' do
+ let(:params) { {} }
- it_behaves_like 'sorts by created_at descending'
- end
+ it_behaves_like 'sorts by created_at descending'
+ end
- %w(created_date created_at_desc).each do |sort|
- context "with sort param equal to #{sort}" do
- let(:params) { { sort: sort } }
+ %w(created_date created_at_desc).each do |sort|
+ context "with sort param equal to #{sort}" do
+ let(:params) { { sort: sort } }
- it_behaves_like 'sorts by created_at descending'
+ it_behaves_like 'sorts by created_at descending'
+ end
end
- end
- context 'with sort param equal to created_at_asc' do
- let(:params) { { sort: 'created_at_asc' } }
+ context 'with sort param equal to created_at_asc' do
+ let(:params) { { sort: 'created_at_asc' } }
- it 'sorts by created_at ascending' do
- is_expected.to eq [runner1, runner2, runner3]
+ it 'sorts by created_at ascending' do
+ is_expected.to eq [runner1, runner2, runner3]
+ end
end
- end
- context 'with sort param equal to contacted_asc' do
- let(:params) { { sort: 'contacted_asc' } }
+ context 'with sort param equal to contacted_asc' do
+ let(:params) { { sort: 'contacted_asc' } }
- it 'sorts by contacted_at ascending' do
- is_expected.to eq [runner2, runner3, runner1]
+ it 'sorts by contacted_at ascending' do
+ is_expected.to eq [runner2, runner3, runner1]
+ end
end
- end
- context 'with sort param equal to contacted_desc' do
- let(:params) { { sort: 'contacted_desc' } }
+ context 'with sort param equal to contacted_desc' do
+ let(:params) { { sort: 'contacted_desc' } }
- it 'sorts by contacted_at descending' do
- is_expected.to eq [runner1, runner3, runner2]
+ it 'sorts by contacted_at descending' do
+ is_expected.to eq [runner1, runner3, runner2]
+ end
end
- end
- context 'with sort param equal to token_expires_at_asc' do
- let(:params) { { sort: 'token_expires_at_asc' } }
+ context 'with sort param equal to token_expires_at_asc' do
+ let(:params) { { sort: 'token_expires_at_asc' } }
- it 'sorts by contacted_at ascending' do
- is_expected.to eq [runner2, runner1, runner3]
+ it 'sorts by contacted_at ascending' do
+ is_expected.to eq [runner2, runner1, runner3]
+ end
end
- end
- context 'with sort param equal to token_expires_at_desc' do
- let(:params) { { sort: 'token_expires_at_desc' } }
+ context 'with sort param equal to token_expires_at_desc' do
+ let(:params) { { sort: 'token_expires_at_desc' } }
- it 'sorts by contacted_at descending' do
- is_expected.to eq [runner3, runner1, runner2]
+ it 'sorts by contacted_at descending' do
+ is_expected.to eq [runner3, runner1, runner2]
+ end
end
end
end
- context 'by non admin user' do
+ shared_examples 'executes as normal user' do
it 'returns no runners' do
user = create :user
create :ci_runner, active: true
@@ -229,6 +231,24 @@ RSpec.describe Ci::RunnersFinder do
end
end
+ context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do
+ it_behaves_like 'executes as admin'
+ end
+
+ context 'when admin mode setting is enabled' do
+ context 'when in admin mode', :enable_admin_mode do
+ it_behaves_like 'executes as admin'
+ end
+
+ context 'when not in admin mode' do
+ it_behaves_like 'executes as normal user'
+ end
+ end
+
+ context 'by non admin user' do
+ it_behaves_like 'executes as normal user'
+ end
+
context 'when user is nil' do
it 'returns no runners' do
user = nil
@@ -473,4 +493,153 @@ RSpec.describe Ci::RunnersFinder do
end
end
end
+
+ context 'project' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:other_project) { create(:project) }
+
+ let(:extra_params) { {} }
+ let(:params) { { project: project }.merge(extra_params).reject { |_, v| v.nil? } }
+
+ describe '#execute' do
+ subject { described_class.new(current_user: user, params: params).execute }
+
+ context 'with user as project admin' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'with project runners' do
+ let_it_be(:runner_project) { create(:ci_runner, :project, contacted_at: 7.minutes.ago, projects: [project]) }
+
+ it 'returns runners available to project' do
+ expect(subject).to match_array([runner_project])
+ end
+ end
+
+ context 'with ancestor group runners' do
+ let_it_be(:runner_instance) { create(:ci_runner, contacted_at: 13.minutes.ago) }
+ let_it_be(:runner_group) { create(:ci_runner, :group, contacted_at: 12.minutes.ago, groups: [group]) }
+
+ it 'returns runners available to project' do
+ expect(subject).to match_array([runner_instance, runner_group])
+ end
+ end
+
+ context 'with allowed shared runners' do
+ let_it_be(:runner_instance) { create(:ci_runner, :instance, contacted_at: 13.minutes.ago) }
+
+ it 'returns runners available to project' do
+ expect(subject).to match_array([runner_instance])
+ end
+ end
+
+ context 'with project, ancestor group, and allowed shared runners' do
+ let_it_be(:runner_project) { create(:ci_runner, :project, contacted_at: 7.minutes.ago, projects: [project]) }
+ let_it_be(:runner_group) { create(:ci_runner, :group, contacted_at: 12.minutes.ago, groups: [group]) }
+ let_it_be(:runner_instance) { create(:ci_runner, :instance, contacted_at: 13.minutes.ago) }
+
+ it 'returns runners available to project' do
+ expect(subject).to match_array([runner_project, runner_group, runner_instance])
+ end
+ end
+
+ context 'filtering' do
+ let_it_be(:runner_instance_inactive) { create(:ci_runner, :instance, active: false, contacted_at: 13.minutes.ago) }
+ let_it_be(:runner_instance_active) { create(:ci_runner, :instance, active: true, contacted_at: 13.minutes.ago) }
+ let_it_be(:runner_project_active) { create(:ci_runner, :project, contacted_at: 5.minutes.ago, active: true, projects: [project]) }
+ let_it_be(:runner_project_inactive) { create(:ci_runner, :project, contacted_at: 5.minutes.ago, active: false, projects: [project]) }
+ let_it_be(:runner_other_project_inactive) { create(:ci_runner, :project, contacted_at: 5.minutes.ago, active: false, projects: [other_project]) }
+
+ context 'by search term' do
+ let_it_be(:runner_project_1) { create(:ci_runner, :project, contacted_at: 5.minutes.ago, description: 'runner_project_search', projects: [project]) }
+ let_it_be(:runner_project_2) { create(:ci_runner, :project, contacted_at: 5.minutes.ago, description: 'runner_project', projects: [project]) }
+ let_it_be(:runner_another_project) { create(:ci_runner, :project, contacted_at: 5.minutes.ago, description: 'runner_project_search', projects: [other_project]) }
+
+ let(:extra_params) { { search: 'runner_project_search' } }
+
+ it 'returns the correct runner' do
+ expect(subject).to match_array([runner_project_1])
+ end
+ end
+
+ context 'by active status' do
+ let(:extra_params) { { active: false } }
+
+ it 'returns the correct runners' do
+ expect(subject).to match_array([runner_instance_inactive, runner_project_inactive])
+ end
+ end
+
+ context 'by status' do
+ let(:extra_params) { { status_status: 'paused' } }
+
+ it 'returns correct runner' do
+ expect(subject).to match_array([runner_instance_inactive, runner_project_inactive])
+ end
+ end
+
+ context 'by tag_name' do
+ let_it_be(:runner_project_1) { create(:ci_runner, :project, contacted_at: 3.minutes.ago, tag_list: %w[runner_tag], projects: [project]) }
+ let_it_be(:runner_project_2) { create(:ci_runner, :project, contacted_at: 3.minutes.ago, tag_list: %w[other_tag], projects: [project]) }
+ let_it_be(:runner_other_project) { create(:ci_runner, :project, contacted_at: 3.minutes.ago, tag_list: %w[runner_tag], projects: [other_project]) }
+
+ let(:extra_params) { { tag_name: %w[runner_tag] } }
+
+ it 'returns correct runner' do
+ expect(subject).to match_array([runner_project_1])
+ end
+ end
+
+ context 'by runner type' do
+ let(:extra_params) { { type_type: 'project_type' } }
+
+ it 'returns correct runners' do
+ expect(subject).to match_array([runner_project_active, runner_project_inactive])
+ end
+ end
+ end
+ end
+
+ context 'with user as project developer' do
+ let(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+ end
+
+ it 'returns no runners' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'when user is nil' do
+ let_it_be(:user) { nil }
+
+ it 'returns no runners' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'with nil project_full_path' do
+ let(:project_full_path) { nil }
+
+ it 'returns no runners' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'when on_demand_scans_runner_tags feature flag is disabled' do
+ before do
+ stub_feature_flags(on_demand_scans_runner_tags: false)
+ end
+
+ it 'returns no runners' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+ end
end
diff --git a/spec/finders/clusters/agent_tokens_finder_spec.rb b/spec/finders/clusters/agent_tokens_finder_spec.rb
index 619aca891c1..024e567a16e 100644
--- a/spec/finders/clusters/agent_tokens_finder_spec.rb
+++ b/spec/finders/clusters/agent_tokens_finder_spec.rb
@@ -5,24 +5,43 @@ require 'spec_helper'
RSpec.describe Clusters::AgentTokensFinder do
describe '#execute' do
let_it_be(:project) { create(:project) }
+ let_it_be(:agent) { create(:cluster_agent, project: project) }
let(:user) { create(:user, maintainer_projects: [project]) }
- let(:agent) { create(:cluster_agent, project: project) }
- let(:agent_id) { agent.id }
- let!(:matching_agent_tokens) do
+ let_it_be(:active_agent_tokens) do
[
create(:cluster_agent_token, agent: agent),
- create(:cluster_agent_token, :revoked, agent: agent)
+ create(:cluster_agent_token, agent: agent)
]
end
- subject(:execute) { described_class.new(project, user, agent_id).execute }
+ let_it_be(:revoked_agent_tokens) do
+ [
+ create(:cluster_agent_token, :revoked, agent: agent),
+ create(:cluster_agent_token, :revoked, agent: agent)
+ ]
+ end
- it 'returns the tokens of the specified agent' do
- # creating a token in a different agent to make sure it will not be included in the result
+ before_all do
+ # set up a token under a different agent as a way to verify
+ # that only tokens of a given agent are included in the result
create(:cluster_agent_token, agent: create(:cluster_agent))
+ end
+
+ subject(:execute) { described_class.new(agent, user).execute }
+
+ it { is_expected.to match_array(active_agent_tokens + revoked_agent_tokens) }
- expect(execute).to match_array(matching_agent_tokens)
+ context 'when filtering by status=active' do
+ subject(:execute) { described_class.new(agent, user, status: 'active').execute }
+
+ it { is_expected.to match_array(active_agent_tokens) }
+ end
+
+ context 'when filtering by status=revoked' do
+ subject(:execute) { described_class.new(agent, user, status: 'revoked').execute }
+
+ it { is_expected.to match_array(revoked_agent_tokens) }
end
context 'when user does not have permission' do
@@ -32,16 +51,20 @@ RSpec.describe Clusters::AgentTokensFinder do
project.add_reporter(user)
end
- it 'raises an error' do
- expect { execute }.to raise_error(ActiveRecord::RecordNotFound)
- end
+ it { is_expected.to eq ::Clusters::AgentToken.none }
end
- context 'when agent does not exist' do
- let(:agent_id) { non_existing_record_id }
+ context 'when current_user is nil' do
+ it 'returns an empty list' do
+ result = described_class.new(agent, nil).execute
+ expect(result).to eq ::Clusters::AgentToken.none
+ end
+ end
- it 'raises an error' do
- expect { execute }.to raise_error(ActiveRecord::RecordNotFound)
+ context 'when agent is nil' do
+ it 'returns an empty list' do
+ result = described_class.new(nil, user).execute
+ expect(result).to eq ::Clusters::AgentToken.none
end
end
end
diff --git a/spec/finders/environments/environments_finder_spec.rb b/spec/finders/environments/environments_finder_spec.rb
index 04fbd4067b4..df66bbdc235 100644
--- a/spec/finders/environments/environments_finder_spec.rb
+++ b/spec/finders/environments/environments_finder_spec.rb
@@ -51,15 +51,35 @@ RSpec.describe Environments::EnvironmentsFinder do
end
context 'with search and states' do
+ let_it_be(:environment_available_b) { create(:environment, :available, name: 'test/foldered-env', project: project) }
+
it 'searches environments by name and state' do
result = described_class.new(project, user, search: 'test', states: :available).execute
- expect(result).to contain_exactly(environment_available)
+ expect(result).to contain_exactly(environment_available, environment_available_b)
+ end
+
+ it 'searches environments by name inside folder and state' do
+ result = described_class.new(project, user, search: 'folder', states: :available).execute
+
+ expect(result).to contain_exactly(environment_available_b)
+ end
+
+ context 'when enable_environments_search_within_folder FF is disabled' do
+ before do
+ stub_feature_flags(enable_environments_search_within_folder: false)
+ end
+
+ it 'ignores name inside folder' do
+ result = described_class.new(project, user, search: 'folder', states: :available).execute
+
+ expect(result).to be_empty
+ end
end
end
context 'with id' do
- it 'searches environments by name and state' do
+ it 'searches environments by name and id' do
result = described_class.new(project, user, search: 'test', environment_ids: [environment_available.id]).execute
expect(result).to contain_exactly(environment_available)
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index 704171a737b..43d66d285fa 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe IssuesFinder do
+RSpec.describe IssuesFinder, feature_category: :team_planning do
include_context 'IssuesFinder context'
it_behaves_like 'issues or work items finder', :issue, 'IssuesFinder#execute context'
diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb
index 11de19cfdbc..61be90b267a 100644
--- a/spec/finders/notes_finder_spec.rb
+++ b/spec/finders/notes_finder_spec.rb
@@ -328,6 +328,16 @@ RSpec.describe NotesFinder do
it 'returns the commit' do
expect(subject.target).to eq(commit)
end
+
+ context 'user does not have permission to read_code' do
+ before do
+ allow(Ability).to receive(:allowed?).with(user, :read_code, project).and_return false
+ end
+
+ it 'returns nil' do
+ expect(subject.target).to be_nil
+ end
+ end
end
context 'target_iid' do
diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb
index 21380cb6632..bcd5aef84f9 100644
--- a/spec/finders/personal_access_tokens_finder_spec.rb
+++ b/spec/finders/personal_access_tokens_finder_spec.rb
@@ -2,359 +2,320 @@
require 'spec_helper'
-RSpec.describe PersonalAccessTokensFinder do
- def finder(options = {}, current_user = nil)
- described_class.new(options, current_user)
- end
-
- describe '# searches PATs' do
- using RSpec::Parameterized::TableSyntax
+RSpec.describe PersonalAccessTokensFinder, :enable_admin_mode do
+ using RSpec::Parameterized::TableSyntax
- let_it_be(:time_token) do
- create(:personal_access_token, created_at: DateTime.new(2022, 01, 02),
- last_used_at: DateTime.new(2022, 01, 02))
+ describe '#execute' do
+ let(:admin) { create(:admin) }
+ let(:user) { create(:user) }
+ let(:other_user) { create(:user) }
+ let(:project_bot) { create(:user, :project_bot) }
+
+ let!(:tokens) do
+ {
+ active: create(:personal_access_token, user: user, name: 'my_pat_1'),
+ active_other: create(:personal_access_token, user: other_user, name: 'my_pat_2'),
+ expired: create(:personal_access_token, :expired, user: user),
+ revoked: create(:personal_access_token, :revoked, user: user),
+ active_impersonation: create(:personal_access_token, :impersonation, user: user),
+ expired_impersonation: create(:personal_access_token, :expired, :impersonation, user: user),
+ revoked_impersonation: create(:personal_access_token, :revoked, :impersonation, user: user),
+ bot: create(:personal_access_token, user: project_bot)
+ }
end
- let_it_be(:name_token) { create(:personal_access_token, name: 'test_1') }
-
- let_it_be(:impersonated_token) do
- create(:personal_access_token, :impersonation,
- created_at: DateTime.new(2022, 01, 02),
- last_used_at: DateTime.new(2022, 01, 02),
- name: 'imp_token'
- )
- end
+ let(:params) { {} }
+ let(:current_user) { admin }
- shared_examples 'finding tokens by user and options' do
- subject { finder(option, user).execute }
+ subject { described_class.new(params, current_user).execute }
- it 'finds exactly' do
- subject
+ describe 'by current user' do
+ context 'with no user' do
+ let(:current_user) { nil }
- is_expected.to contain_exactly(*result)
+ it 'returns all tokens' do
+ is_expected.to match_array(tokens.values)
+ end
end
- end
- context 'by' do
- where(:option, :user, :result) do
- { created_before: DateTime.new(2022, 01, 03) } | create(:admin) | lazy { [time_token, impersonated_token] }
- { created_after: DateTime.new(2022, 01, 01) } | create(:admin) | lazy { [time_token, name_token, impersonated_token] }
- { last_used_before: DateTime.new(2022, 01, 03) } | create(:admin) | lazy { [time_token, impersonated_token] }
- { last_used_before: DateTime.new(2022, 01, 03) } | create(:admin) | lazy { [time_token, impersonated_token] }
- { impersonation: true } | create(:admin) | lazy { [impersonated_token] }
- { search: 'test' } | create(:admin) | lazy { [name_token] }
- end
+ context 'with admin' do
+ let(:current_user) { admin }
- with_them do
- it_behaves_like 'finding tokens by user and options'
- end
- end
- 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) }
- let!(:active_impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
- let!(:expired_impersonation_token) { create(:personal_access_token, :expired, :impersonation, user: user) }
- let!(:revoked_impersonation_token) { create(:personal_access_token, :revoked, :impersonation, user: user) }
- let!(:project_bot) { create(:user, :project_bot) }
- let!(:project_member) { create(:project_member, user: project_bot) }
- let!(:project_access_token) { create(:personal_access_token, user: project_bot) }
-
- 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)
+ context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do
+ it 'returns all tokens' do
+ is_expected.to match_array(tokens.values)
+ end
end
- end
- context 'current_user is not allowed to read PATs' do
- let(:current_user) { create(:user) }
+ context 'when admin mode setting is enabled' do
+ context 'when in admin mode', :enable_admin_mode do
+ it 'returns all tokens' do
+ is_expected.to match_array(tokens.values)
+ end
+ end
+
+ context 'when not in admin mode' do
+ before do
+ allow_next_instance_of(Gitlab::Auth::CurrentUserMode) do |current_user_mode|
+ allow(current_user_mode).to receive(:admin_mode?).and_return(false)
+ end
+ end
- it { is_expected.to be_empty }
+ it 'returns no tokens' do
+ is_expected.to be_empty
+ end
+ end
+ end
end
- context 'when user param is not set' do
- let(:params) { {} }
+ context 'when user can read user personal access tokens' do
+ let(:params) { { user: user } }
+ let(:current_user) { user }
- 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, project_access_token)
+ it 'returns tokens of user' do
+ is_expected.to contain_exactly(*user.personal_access_tokens)
end
+ end
- context 'when current_user is not an administrator' do
- let(:current_user) { create(:user) }
+ context 'when user can not read user personal access tokens' do
+ let(:params) { { user: other_user } }
+ let(:current_user) { user }
- it { is_expected.to be_empty }
+ it 'returns no tokens' do
+ is_expected.to be_empty
end
end
end
- describe 'without user' 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, project_access_token)
+ describe 'by user' do
+ where(:by_user, :expected_tokens) do
+ nil | tokens.keys
+ ref(:user) | [:active, :expired, :revoked, :active_impersonation, :expired_impersonation, :revoked_impersonation]
+ ref(:other_user) | [:active_other]
+ ref(:admin) | []
end
- describe 'with users' do
- let(:user2) { create(:user) }
-
- before do
- create(:personal_access_token, user: user2)
- create(:personal_access_token, :expired, user: user2)
- create(:personal_access_token, :revoked, user: user2)
- create(:personal_access_token, :impersonation, user: user2)
- create(:personal_access_token, :expired, :impersonation, user: user2)
- create(:personal_access_token, :revoked, :impersonation, user: user2)
+ with_them do
+ let(:params) { { user: by_user } }
- params[:users] = [user]
+ it 'returns tokens by user' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
-
- it {
- 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
- describe 'with sort order' do
- before do
- params[:sort] = 'id_asc'
- end
-
- it 'sorts records as per the specified sort order' do
- expect(subject).to match_array(PersonalAccessToken.all.order(id: :asc))
- end
+ describe 'by users' do
+ where(:by_users, :expected_tokens) do
+ nil | tokens.keys
+ lazy { [user] } | [:active, :expired, :revoked, :active_impersonation, :expired_impersonation, :revoked_impersonation]
+ lazy { [other_user] } | [:active_other]
+ lazy { [user, other_user] } | [:active, :active_other, :expired, :revoked, :active_impersonation, :expired_impersonation, :revoked_impersonation]
+ [] | [] # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
end
- describe 'without impersonation' do
- before do
- params[:impersonation] = false
- end
-
- it { is_expected.to contain_exactly(active_personal_access_token, revoked_personal_access_token, expired_personal_access_token, project_access_token) }
-
- describe 'with active state' do
- before do
- params[:state] = 'active'
- end
-
- it { is_expected.to contain_exactly(active_personal_access_token, project_access_token) }
- end
-
- describe 'with inactive state' do
- before do
- params[:state] = 'inactive'
- end
+ with_them do
+ let(:params) { { users: by_users } }
- it { is_expected.to contain_exactly(revoked_personal_access_token, expired_personal_access_token) }
+ it 'returns tokens by users' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
end
+ end
- describe 'with impersonation' do
- before do
- params[:impersonation] = true
- end
-
- it { is_expected.to contain_exactly(active_impersonation_token, revoked_impersonation_token, expired_impersonation_token) }
-
- describe 'with active state' do
- before do
- params[:state] = 'active'
- end
-
- it { is_expected.to contain_exactly(active_impersonation_token) }
- end
+ describe 'by impersonation' do
+ where(:by_impersonation, :expected_tokens) do
+ nil | tokens.keys
+ true | [:active_impersonation, :expired_impersonation, :revoked_impersonation]
+ false | [:active, :active_other, :expired, :revoked, :bot]
+ 'other' | tokens.keys
+ end
- describe 'with inactive state' do
- before do
- params[:state] = 'inactive'
- end
+ with_them do
+ let(:params) { { impersonation: by_impersonation } }
- it { is_expected.to contain_exactly(revoked_impersonation_token, expired_impersonation_token) }
+ it 'returns tokens by impersonation' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
end
+ end
- describe 'with active state' do
- before do
- params[:state] = 'active'
- end
-
- it { is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token, project_access_token) }
+ describe 'by state' do
+ where(:by_state, :expected_tokens) do
+ nil | tokens.keys
+ 'active' | [:active, :active_other, :active_impersonation, :bot]
+ 'inactive' | [:expired, :revoked, :expired_impersonation, :revoked_impersonation]
+ 'other' | tokens.keys
end
- describe 'with inactive state' do
- before do
- params[:state] = 'inactive'
- end
+ with_them do
+ let(:params) { { state: by_state } }
- it do
- is_expected.to contain_exactly(expired_personal_access_token, revoked_personal_access_token,
- expired_impersonation_token, revoked_impersonation_token)
+ it 'returns tokens by state' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
end
+ end
- describe 'with id' do
- subject { finder(params).find_by_id(active_personal_access_token.id) }
-
- it { is_expected.to eq(active_personal_access_token) }
+ describe 'by owner type' do
+ where(:by_owner_type, :expected_tokens) do
+ nil | tokens.keys
+ 'human' | [:active, :active_other, :expired, :revoked, :active_impersonation, :expired_impersonation, :revoked_impersonation]
+ 'other' | tokens.keys
+ end
- describe 'with impersonation' do
- before do
- params[:impersonation] = true
- end
+ with_them do
+ let(:params) { { owner_type: by_owner_type } }
- it { is_expected.to be_nil }
+ it 'returns tokens by owner type' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
end
+ end
- describe 'with token' do
- subject { finder(params).find_by_token(active_personal_access_token.token) }
-
- it { is_expected.to eq(active_personal_access_token) }
+ describe 'by revoked state' do
+ where(:by_revoked_state, :expected_tokens) do
+ nil | [:active, :active_other, :expired, :active_impersonation, :expired_impersonation, :bot]
+ true | [:revoked, :revoked_impersonation]
+ false | [:active, :active_other, :expired, :active_impersonation, :expired_impersonation, :bot]
+ end
- describe 'with impersonation' do
- before do
- params[:impersonation] = true
- end
+ with_them do
+ let(:params) { { revoked: by_revoked_state } }
- it { is_expected.to be_nil }
+ it 'returns tokens by revoked state' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
end
end
- describe 'with user' do
- let(:user2) { create(:user) }
- let!(:other_user_active_personal_access_token) { create(:personal_access_token, user: user2) }
- let!(:other_user_expired_personal_access_token) { create(:personal_access_token, :expired, user: user2) }
- let!(:other_user_revoked_personal_access_token) { create(:personal_access_token, :revoked, user: user2) }
- let!(:other_user_active_impersonation_token) { create(:personal_access_token, :impersonation, user: user2) }
- let!(:other_user_expired_impersonation_token) { create(:personal_access_token, :expired, :impersonation, user: user2) }
- let!(:other_user_revoked_impersonation_token) { create(:personal_access_token, :revoked, :impersonation, user: user2) }
-
+ describe 'by created date' do
before do
- params[:user] = user
- end
-
- 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)
+ tokens[:active_other].update!(created_at: 5.days.ago)
end
- describe 'filtering human tokens' do
- before do
- params[:owner_type] = 'human'
+ describe 'by created before' do
+ where(:by_created_before, :expected_tokens) do
+ 6.days.ago | []
+ 2.days.ago | [:active_other]
+ 2.days.from_now | tokens.keys
end
- it { is_expected.not_to include(project_access_token) }
+ with_them do
+ let(:params) { { created_before: by_created_before } }
+
+ it 'returns tokens by created before' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
+ end
+ end
end
- describe 'without impersonation' do
- before do
- params[:impersonation] = false
+ describe 'by created after' do
+ where(:by_created_after, :expected_tokens) do
+ 6.days.ago | tokens.keys
+ 2.days.ago | [:active, :expired, :revoked, :active_impersonation, :expired_impersonation, :revoked_impersonation, :bot]
+ 2.days.from_now | []
end
- it { is_expected.to contain_exactly(active_personal_access_token, revoked_personal_access_token, expired_personal_access_token) }
+ with_them do
+ let(:params) { { created_after: by_created_after } }
- describe 'with active state' do
- before do
- params[:state] = 'active'
+ it 'returns tokens by created before' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
-
- it { is_expected.to contain_exactly(active_personal_access_token) }
end
+ end
+ end
- describe 'with inactive state' do
- before do
- params[:state] = 'inactive'
- end
-
- it { is_expected.to contain_exactly(revoked_personal_access_token, expired_personal_access_token) }
- end
+ describe 'by last used date' do
+ before do
+ PersonalAccessToken.update_all(last_used_at: Time.now)
+ tokens[:active_other].update!(last_used_at: 5.days.ago)
end
- describe 'with impersonation' do
- before do
- params[:impersonation] = true
+ describe 'by last used before' do
+ where(:by_last_used_before, :expected_tokens) do
+ 6.days.ago | []
+ 2.days.ago | [:active_other]
+ 2.days.from_now | tokens.keys
end
- it { is_expected.to contain_exactly(active_impersonation_token, revoked_impersonation_token, expired_impersonation_token) }
+ with_them do
+ let(:params) { { last_used_before: by_last_used_before } }
- describe 'with active state' do
- before do
- params[:state] = 'active'
+ it 'returns tokens by last used before' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
+ end
+ end
- it { is_expected.to contain_exactly(active_impersonation_token) }
+ describe 'by last used after' do
+ where(:by_last_used_after, :expected_tokens) do
+ 6.days.ago | tokens.keys
+ 2.days.ago | [:active, :expired, :revoked, :active_impersonation, :expired_impersonation, :revoked_impersonation, :bot]
+ 2.days.from_now | []
end
- describe 'with inactive state' do
- before do
- params[:state] = 'inactive'
- end
+ with_them do
+ let(:params) { { last_used_after: by_last_used_after } }
- it { is_expected.to contain_exactly(revoked_impersonation_token, expired_impersonation_token) }
+ it 'returns tokens by last used after' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
+ end
end
end
+ end
- describe 'with active state' do
- before do
- params[:state] = 'active'
- end
-
- it { is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token) }
+ describe 'by search' do
+ where(:by_search, :expected_tokens) do
+ nil | tokens.keys
+ 'my_pat' | [:active, :active_other]
+ 'other' | []
end
- describe 'with inactive state' do
- before do
- params[:state] = 'inactive'
- end
+ with_them do
+ let(:params) { { search: by_search } }
- it do
- is_expected.to contain_exactly(expired_personal_access_token, revoked_personal_access_token,
- expired_impersonation_token, revoked_impersonation_token)
+ it 'returns tokens by search' do
+ is_expected.to match_array(tokens.values_at(*expected_tokens))
end
end
+ end
- describe 'with id' do
- subject { finder(params).find_by_id(active_personal_access_token.id) }
-
- it { is_expected.to eq(active_personal_access_token) }
+ describe 'sort' do
+ where(:sort, :expected_tokens) do
+ nil | tokens.keys
+ 'id_asc' | [:active, :active_other, :expired, :revoked, :active_impersonation, :expired_impersonation, :revoked_impersonation, :bot]
+ 'id_desc' | [:bot, :revoked_impersonation, :expired_impersonation, :active_impersonation, :revoked, :expired, :active_other, :active]
+ 'other' | tokens.keys
+ end
- describe 'with impersonation' do
- before do
- params[:impersonation] = true
- end
+ with_them do
+ let(:params) { { sort: sort } }
- it { is_expected.to be_nil }
+ it 'returns ordered tokens' do
+ expect(subject.map(&:id)).to eq(tokens.values_at(*expected_tokens).map(&:id))
end
end
+ end
- describe 'with token' do
- subject { finder(params).find_by_token(active_personal_access_token.token) }
+ describe 'delegates' do
+ subject { described_class.new(params, current_user) }
- it { is_expected.to eq(active_personal_access_token) }
+ describe '#find_by_id' do
+ it 'returns token by id' do
+ expect(subject.find_by_id(tokens[:active].id)).to eq(tokens[:active])
+ end
+ end
- describe 'with impersonation' do
- before do
- params[:impersonation] = true
- end
+ describe '#find_by_token' do
+ it 'returns token by token' do
+ expect(subject.find_by_token(tokens[:active].token)).to eq(tokens[:active])
+ end
+ end
- it { is_expected.to be_nil }
+ describe '#find' do
+ it 'returns token by id' do
+ expect(subject.find(tokens[:active].id)).to eq(tokens[:active])
end
end
end
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 02153715eac..9fecbfb71fc 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -392,6 +392,23 @@ RSpec.describe ProjectsFinder do
it { is_expected.to match_array([project]) }
end
+ describe 'filter by language' do
+ let_it_be(:ruby) { create(:programming_language, name: 'Ruby') }
+ let_it_be(:repository_language) { create(:repository_language, project: internal_project, programming_language: ruby) }
+
+ let(:params) { { language: ruby.id } }
+
+ it { is_expected.to match_array([internal_project]) }
+
+ context 'when project_language_search feature flag disabled' do
+ before do
+ stub_feature_flags(project_language_search: false)
+ end
+
+ it { is_expected.to match_array([internal_project, public_project]) }
+ end
+ end
+
describe 'sorting' do
let_it_be(:more_projects) do
[
diff --git a/spec/finders/tags_finder_spec.rb b/spec/finders/tags_finder_spec.rb
index 0bf9b228c8a..2af23c466fb 100644
--- a/spec/finders/tags_finder_spec.rb
+++ b/spec/finders/tags_finder_spec.rb
@@ -68,6 +68,14 @@ RSpec.describe TagsFinder do
expect(result.count).to eq(1)
end
+ it 'filters tags by name with wildcard' do
+ result = load_tags({ search: 'v1.*.0' })
+
+ expect(result.first.name).to eq('v1.0.0')
+ expect(result.second.name).to eq('v1.1.0')
+ expect(result.count).to eq(2)
+ end
+
it 'filters tags by nonexistent name that begins with' do
result = load_tags({ search: '^nope' })
@@ -79,6 +87,11 @@ RSpec.describe TagsFinder do
expect(result.count).to eq(0)
end
+ it 'filters tags by nonexistent name with wildcard' do
+ result = load_tags({ search: 'n*e' })
+ expect(result.count).to eq(0)
+ end
+
context 'when search is not a string' do
it 'returns no matches' do
result = load_tags({ search: { 'a' => 'b' } })
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index 5611a67e977..bcead6b0170 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -327,9 +327,9 @@ RSpec.describe TodosFinder do
it 'returns the expected types' do
expected_result =
if Gitlab.ee?
- %w[Epic Issue MergeRequest DesignManagement::Design AlertManagement::Alert]
+ %w[Epic Issue WorkItem MergeRequest DesignManagement::Design AlertManagement::Alert]
else
- %w[Issue MergeRequest DesignManagement::Design AlertManagement::Alert]
+ %w[Issue WorkItem MergeRequest DesignManagement::Design AlertManagement::Alert]
end
expect(described_class.todo_types).to contain_exactly(*expected_result)
diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb
index 271dce44db7..5cf845a87b2 100644
--- a/spec/finders/users_finder_spec.rb
+++ b/spec/finders/users_finder_spec.rb
@@ -8,9 +8,7 @@ RSpec.describe UsersFinder do
let_it_be(:project_bot) { create(:user, :project_bot) }
- context 'with a normal user' do
- let_it_be(:user) { create(:user) }
-
+ shared_examples 'executes users finder as normal user' do
it 'returns searchable users' do
users = described_class.new(user).execute
@@ -97,37 +95,35 @@ RSpec.describe UsersFinder do
end
end
- context 'with an admin user', :enable_admin_mode do
- let_it_be(:admin) { create(:admin) }
-
+ shared_examples 'executes users finder as admin' do
it 'filters by external users' do
- users = described_class.new(admin, external: true).execute
+ users = described_class.new(user, external: true).execute
expect(users).to contain_exactly(external_user)
end
it 'returns all users' do
- users = described_class.new(admin).execute
+ users = described_class.new(user).execute
- expect(users).to contain_exactly(admin, normal_user, blocked_user, unconfirmed_user, banned_user, external_user, omniauth_user, internal_user, admin_user, project_bot)
+ expect(users).to contain_exactly(user, normal_user, blocked_user, unconfirmed_user, banned_user, external_user, omniauth_user, internal_user, admin_user, project_bot)
end
it 'filters by blocked users' do
- users = described_class.new(admin, blocked: true).execute
+ users = described_class.new(user, blocked: true).execute
expect(users).to contain_exactly(blocked_user)
end
it 'filters by active users' do
- users = described_class.new(admin, active: true).execute
+ users = described_class.new(user, active: true).execute
- expect(users).to contain_exactly(admin, normal_user, unconfirmed_user, external_user, omniauth_user, admin_user, project_bot)
+ expect(users).to contain_exactly(user, normal_user, unconfirmed_user, external_user, omniauth_user, admin_user, project_bot)
end
it 'returns only admins' do
- users = described_class.new(admin, admins: true).execute
+ users = described_class.new(user, admins: true).execute
- expect(users).to contain_exactly(admin, admin_user)
+ expect(users).to contain_exactly(user, admin_user)
end
it 'filters by custom attributes' do
@@ -137,7 +133,7 @@ RSpec.describe UsersFinder do
create :user_custom_attribute, user: internal_user, key: 'foo', value: 'foo'
users = described_class.new(
- admin,
+ user,
custom_attributes: { foo: 'foo', bar: 'bar' }
).execute
@@ -145,10 +141,34 @@ RSpec.describe UsersFinder do
end
it 'filters by private emails search' do
- users = described_class.new(admin, search: normal_user.email).execute
+ users = described_class.new(user, search: normal_user.email).execute
expect(users).to contain_exactly(normal_user)
end
end
+
+ context 'with a normal user' do
+ let_it_be(:user) { create(:user) }
+
+ it_behaves_like 'executes users finder as normal user'
+ end
+
+ context 'with an admin user' do
+ let_it_be(:user) { create(:admin) }
+
+ context 'when admin mode setting is disabled', :do_not_mock_admin_mode_setting do
+ it_behaves_like 'executes users finder as admin'
+ end
+
+ context 'when admin mode setting is enabled' do
+ context 'when in admin mode', :enable_admin_mode do
+ it_behaves_like 'executes users finder as admin'
+ end
+
+ context 'when not in admin mode' do
+ it_behaves_like 'executes users finder as normal user'
+ end
+ end
+ end
end
end
diff --git a/spec/finders/work_items/work_items_finder_spec.rb b/spec/finders/work_items/work_items_finder_spec.rb
index fe400688a23..ab8a9ba9204 100644
--- a/spec/finders/work_items/work_items_finder_spec.rb
+++ b/spec/finders/work_items/work_items_finder_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe WorkItems::WorkItemsFinder do
+RSpec.describe WorkItems::WorkItemsFinder, feature_category: :team_planning do
using RSpec::Parameterized::TableSyntax
include_context 'WorkItemsFinder context'