summaryrefslogtreecommitdiff
path: root/spec/finders
diff options
context:
space:
mode:
Diffstat (limited to 'spec/finders')
-rw-r--r--spec/finders/bulk_imports/entities_finder_spec.rb32
-rw-r--r--spec/finders/bulk_imports/imports_finder_spec.rb24
-rw-r--r--spec/finders/ci/jobs_finder_spec.rb22
-rw-r--r--spec/finders/concerns/finder_methods_spec.rb51
-rw-r--r--spec/finders/concerns/finder_with_cross_project_access_spec.rb4
-rw-r--r--spec/finders/keys_finder_spec.rb55
-rw-r--r--spec/finders/packages/build_infos_for_many_packages_finder_spec.rb136
-rw-r--r--spec/finders/packages/group_packages_finder_spec.rb16
-rw-r--r--spec/finders/packages/packages_finder_spec.rb16
-rw-r--r--spec/finders/releases/group_releases_finder_spec.rb15
-rw-r--r--spec/finders/user_recent_events_finder_spec.rb356
-rw-r--r--spec/finders/users_finder_spec.rb50
12 files changed, 537 insertions, 240 deletions
diff --git a/spec/finders/bulk_imports/entities_finder_spec.rb b/spec/finders/bulk_imports/entities_finder_spec.rb
index e053011b60d..54c792cb4d8 100644
--- a/spec/finders/bulk_imports/entities_finder_spec.rb
+++ b/spec/finders/bulk_imports/entities_finder_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe BulkImports::EntitiesFinder do
end
context 'when status is specified' do
- subject { described_class.new(user: user, status: 'failed') }
+ subject { described_class.new(user: user, params: { status: 'failed' }) }
it 'returns a list of import entities filtered by status' do
expect(subject.execute)
@@ -61,7 +61,7 @@ RSpec.describe BulkImports::EntitiesFinder do
end
context 'when invalid status is specified' do
- subject { described_class.new(user: user, status: 'invalid') }
+ subject { described_class.new(user: user, params: { status: 'invalid' }) }
it 'does not filter entities by status' do
expect(subject.execute)
@@ -74,11 +74,37 @@ RSpec.describe BulkImports::EntitiesFinder do
end
context 'when bulk import and status are specified' do
- subject { described_class.new(user: user, bulk_import: user_import_2, status: 'finished') }
+ subject { described_class.new(user: user, bulk_import: user_import_2, params: { status: 'finished' }) }
it 'returns matched import entities' do
expect(subject.execute).to contain_exactly(finished_entity_2)
end
end
+
+ context 'when order is specifed' do
+ subject { described_class.new(user: user, params: { sort: order }) }
+
+ context 'when order is specified as asc' do
+ let(:order) { :asc }
+
+ it 'returns entities sorted ascending' do
+ expect(subject.execute).to eq([
+ started_entity_1, finished_entity_1, failed_entity_1,
+ started_entity_2, finished_entity_2, failed_entity_2
+ ])
+ end
+ end
+
+ context 'when order is specified as desc' do
+ let(:order) { :desc }
+
+ it 'returns entities sorted descending' do
+ expect(subject.execute).to eq([
+ failed_entity_2, finished_entity_2, started_entity_2,
+ failed_entity_1, finished_entity_1, started_entity_1
+ ])
+ end
+ end
+ end
end
end
diff --git a/spec/finders/bulk_imports/imports_finder_spec.rb b/spec/finders/bulk_imports/imports_finder_spec.rb
index aac83c86c84..2f550514a33 100644
--- a/spec/finders/bulk_imports/imports_finder_spec.rb
+++ b/spec/finders/bulk_imports/imports_finder_spec.rb
@@ -16,19 +16,39 @@ RSpec.describe BulkImports::ImportsFinder do
end
context 'when status is specified' do
- subject { described_class.new(user: user, status: 'started') }
+ subject { described_class.new(user: user, params: { status: 'started' }) }
it 'returns a list of import entities filtered by status' do
expect(subject.execute).to contain_exactly(started_import)
end
context 'when invalid status is specified' do
- subject { described_class.new(user: user, status: 'invalid') }
+ subject { described_class.new(user: user, params: { status: 'invalid' }) }
it 'does not filter entities by status' do
expect(subject.execute).to contain_exactly(started_import, finished_import)
end
end
end
+
+ context 'when order is specifed' do
+ subject { described_class.new(user: user, params: { sort: order }) }
+
+ context 'when order is specified as asc' do
+ let(:order) { :asc }
+
+ it 'returns entities sorted ascending' do
+ expect(subject.execute).to eq([started_import, finished_import])
+ end
+ end
+
+ context 'when order is specified as desc' do
+ let(:order) { :desc }
+
+ it 'returns entities sorted descending' do
+ expect(subject.execute).to eq([finished_import, started_import])
+ end
+ end
+ end
end
end
diff --git a/spec/finders/ci/jobs_finder_spec.rb b/spec/finders/ci/jobs_finder_spec.rb
index 959716b1fd3..45e8cf5a582 100644
--- a/spec/finders/ci/jobs_finder_spec.rb
+++ b/spec/finders/ci/jobs_finder_spec.rb
@@ -7,9 +7,9 @@ RSpec.describe Ci::JobsFinder, '#execute' do
let_it_be(:admin) { create(:user, :admin) }
let_it_be(:project) { create(:project, :private, public_builds: false) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
- let_it_be(:job_1) { create(:ci_build) }
- let_it_be(:job_2) { create(:ci_build, :running) }
- let_it_be(:job_3) { create(:ci_build, :success, pipeline: pipeline, name: 'build') }
+ let_it_be(:pending_job) { create(:ci_build, :pending) }
+ let_it_be(:running_job) { create(:ci_build, :running) }
+ let_it_be(:successful_job) { create(:ci_build, :success, pipeline: pipeline, name: 'build') }
let(:params) { {} }
@@ -17,7 +17,7 @@ RSpec.describe Ci::JobsFinder, '#execute' do
subject { described_class.new(current_user: admin, params: params).execute }
it 'returns all jobs' do
- expect(subject).to match_array([job_1, job_2, job_3])
+ expect(subject).to match_array([pending_job, running_job, successful_job])
end
context 'non admin user' do
@@ -37,7 +37,7 @@ RSpec.describe Ci::JobsFinder, '#execute' do
end
context 'scope is present' do
- let(:jobs) { [job_1, job_2, job_3] }
+ let(:jobs) { [pending_job, running_job, successful_job] }
where(:scope, :index) do
[
@@ -55,11 +55,11 @@ RSpec.describe Ci::JobsFinder, '#execute' do
end
context 'scope is an array' do
- let(:jobs) { [job_1, job_2, job_3] }
- let(:params) {{ scope: ['running'] }}
+ 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 match_array([job_2])
+ expect(subject).to contain_exactly(running_job, successful_job)
end
end
end
@@ -73,7 +73,7 @@ RSpec.describe Ci::JobsFinder, '#execute' do
end
it 'returns jobs for the specified project' do
- expect(subject).to match_array([job_3])
+ expect(subject).to match_array([successful_job])
end
end
@@ -99,7 +99,7 @@ RSpec.describe Ci::JobsFinder, '#execute' do
context 'when pipeline is present' do
before_all do
project.add_maintainer(user)
- job_3.update!(retried: true)
+ successful_job.update!(retried: true)
end
let_it_be(:job_4) { create(:ci_build, :success, pipeline: pipeline, name: 'build') }
@@ -122,7 +122,7 @@ RSpec.describe Ci::JobsFinder, '#execute' do
let(:params) { { include_retried: true } }
it 'returns retried jobs' do
- expect(subject).to match_array([job_3, job_4])
+ expect(subject).to match_array([successful_job, job_4])
end
end
end
diff --git a/spec/finders/concerns/finder_methods_spec.rb b/spec/finders/concerns/finder_methods_spec.rb
index 195449d70c3..09ec8110129 100644
--- a/spec/finders/concerns/finder_methods_spec.rb
+++ b/spec/finders/concerns/finder_methods_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe FinderMethods do
end
def execute
- Project.all.order(id: :desc)
+ Project.where.not(name: 'foo').order(id: :desc)
end
private
@@ -21,22 +21,30 @@ RSpec.describe FinderMethods do
end
end
- let(:user) { create(:user) }
- let(:finder) { finder_class.new(user) }
- let(:authorized_project) { create(:project) }
- let(:unauthorized_project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:authorized_project) { create(:project) }
+ let_it_be(:unmatched_project) { create(:project, name: 'foo') }
+ let_it_be(:unauthorized_project) { create(:project) }
- before do
+ subject(:finder) { finder_class.new(user) }
+
+ before_all do
authorized_project.add_developer(user)
+ unmatched_project.add_developer(user)
end
+ # rubocop:disable Rails/FindById
describe '#find_by!' do
it 'returns the project if the user has access' do
expect(finder.find_by!(id: authorized_project.id)).to eq(authorized_project)
end
- it 'raises not found when the project is not found' do
- expect { finder.find_by!(id: 0) }.to raise_error(ActiveRecord::RecordNotFound)
+ it 'raises not found when the project is not found by id' do
+ expect { finder.find_by!(id: non_existing_record_id) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'raises not found when the project is not found by filter' do
+ expect { finder.find_by!(id: unmatched_project.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
it 'raises not found the user does not have access' do
@@ -53,19 +61,34 @@ RSpec.describe FinderMethods do
finder.find_by!(id: authorized_project.id)
end
end
+ # rubocop:enable Rails/FindById
describe '#find' do
it 'returns the project if the user has access' do
expect(finder.find(authorized_project.id)).to eq(authorized_project)
end
- it 'raises not found when the project is not found' do
- expect { finder.find(0) }.to raise_error(ActiveRecord::RecordNotFound)
+ it 'raises not found when the project is not found by id' do
+ expect { finder.find(non_existing_record_id) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'raises not found when the project is not found by filter' do
+ expect { finder.find(unmatched_project.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
it 'raises not found the user does not have access' do
expect { finder.find(unauthorized_project.id) }.to raise_error(ActiveRecord::RecordNotFound)
end
+
+ it 'ignores ordering' do
+ # Memoise the finder result so we can add message expectations to it
+ relation = finder.execute
+ allow(finder).to receive(:execute).and_return(relation)
+
+ expect(relation).to receive(:reorder).with(nil).and_call_original
+
+ finder.find(authorized_project.id)
+ end
end
describe '#find_by' do
@@ -73,8 +96,12 @@ RSpec.describe FinderMethods do
expect(finder.find_by(id: authorized_project.id)).to eq(authorized_project)
end
- it 'returns nil when the project is not found' do
- expect(finder.find_by(id: 0)).to be_nil
+ it 'returns nil when the project is not found by id' do
+ expect(finder.find_by(id: non_existing_record_id)).to be_nil
+ end
+
+ it 'returns nil when the project is not found by filter' do
+ expect(finder.find_by(id: unmatched_project.id)).to be_nil
end
it 'returns nil when the user does not have access' do
diff --git a/spec/finders/concerns/finder_with_cross_project_access_spec.rb b/spec/finders/concerns/finder_with_cross_project_access_spec.rb
index 116b523bd99..0798528c200 100644
--- a/spec/finders/concerns/finder_with_cross_project_access_spec.rb
+++ b/spec/finders/concerns/finder_with_cross_project_access_spec.rb
@@ -93,11 +93,11 @@ RSpec.describe FinderWithCrossProjectAccess do
it 'checks the accessibility of the subject directly' do
expect_access_check_on_result
- finder.find_by!(id: result.id)
+ finder.find(result.id)
end
it 're-enables the check after the find failed' do
- finder.find_by!(id: non_existing_record_id) rescue ActiveRecord::RecordNotFound
+ finder.find(non_existing_record_id) rescue ActiveRecord::RecordNotFound
expect(finder.instance_variable_get(:@should_skip_cross_project_check))
.to eq(false)
diff --git a/spec/finders/keys_finder_spec.rb b/spec/finders/keys_finder_spec.rb
index 277c852c953..332aa7afde1 100644
--- a/spec/finders/keys_finder_spec.rb
+++ b/spec/finders/keys_finder_spec.rb
@@ -5,23 +5,22 @@ require 'spec_helper'
RSpec.describe KeysFinder do
subject { described_class.new(params).execute }
- let(:user) { create(:user) }
- let(:params) { {} }
-
- let!(:key_1) do
- create(:personal_key,
+ let_it_be(:user) { create(:user) }
+ let_it_be(:key_1) do
+ create(:rsa_key_4096,
last_used_at: 7.days.ago,
user: user,
- key: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1016k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=',
- fingerprint: 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1',
- fingerprint_sha256: 'nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg')
+ fingerprint: 'df:73:db:29:3c:a5:32:cf:09:17:7e:8e:9d:de:d7:f7',
+ fingerprint_sha256: 'ByDU7hQ1JB95l6p53rHrffc4eXvEtqGUtQhS+Dhyy7g')
end
- let!(:key_2) { create(:personal_key, last_used_at: nil, user: user) }
- let!(:key_3) { create(:personal_key, last_used_at: 2.days.ago) }
+ let_it_be(:key_2) { create(:personal_key_4096, last_used_at: nil, user: user) }
+ let_it_be(:key_3) { create(:personal_key_4096, last_used_at: 2.days.ago) }
+
+ let(:params) { {} }
context 'key_type' do
- let!(:deploy_key) { create(:deploy_key) }
+ let_it_be(:deploy_key) { create(:deploy_key) }
context 'when `key_type` is `ssh`' do
before do
@@ -64,35 +63,41 @@ RSpec.describe KeysFinder do
end
context 'with valid fingerprints' do
- let!(:deploy_key) do
- create(:deploy_key,
- user: user,
- key: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1017k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=',
- fingerprint: '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4',
- fingerprint_sha256: '4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk')
- end
+ let_it_be(:deploy_key) { create(:rsa_deploy_key_5120, user: user) }
context 'personal key with valid MD5 params' do
context 'with an existent fingerprint' do
before do
- params[:fingerprint] = 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
+ params[:fingerprint] = 'df:73:db:29:3c:a5:32:cf:09:17:7e:8e:9d:de:d7:f7'
end
it 'returns the key' do
expect(subject).to eq(key_1)
expect(subject.user).to eq(user)
end
+
+ context 'with FIPS mode', :fips_mode do
+ it 'raises InvalidFingerprint' do
+ expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
+ end
+ end
end
context 'deploy key with an existent fingerprint' do
before do
- params[:fingerprint] = '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4'
+ params[:fingerprint] = 'fe:fa:3a:4d:7d:51:ec:bf:c7:64:0c:96:d0:17:8a:d0'
end
it 'returns the key' do
expect(subject).to eq(deploy_key)
expect(subject.user).to eq(user)
end
+
+ context 'with FIPS mode', :fips_mode do
+ it 'raises InvalidFingerprint' do
+ expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
+ end
+ end
end
context 'with a non-existent fingerprint' do
@@ -103,13 +108,19 @@ RSpec.describe KeysFinder do
it 'returns nil' do
expect(subject).to be_nil
end
+
+ context 'with FIPS mode', :fips_mode do
+ it 'raises InvalidFingerprint' do
+ expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
+ end
+ end
end
end
context 'personal key with valid SHA256 params' do
context 'with an existent fingerprint' do
before do
- params[:fingerprint] = 'SHA256:nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
+ params[:fingerprint] = 'SHA256:ByDU7hQ1JB95l6p53rHrffc4eXvEtqGUtQhS+Dhyy7g'
end
it 'returns key' do
@@ -120,7 +131,7 @@ RSpec.describe KeysFinder do
context 'deploy key with an existent fingerprint' do
before do
- params[:fingerprint] = 'SHA256:4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk'
+ params[:fingerprint] = 'SHA256:PCCupLbFHScm4AbEufbGDvhBU27IM0MVAor715qKQK8'
end
it 'returns key' do
diff --git a/spec/finders/packages/build_infos_for_many_packages_finder_spec.rb b/spec/finders/packages/build_infos_for_many_packages_finder_spec.rb
new file mode 100644
index 00000000000..f3c79d0c825
--- /dev/null
+++ b/spec/finders/packages/build_infos_for_many_packages_finder_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Packages::BuildInfosForManyPackagesFinder do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:package) { create(:package) }
+ let_it_be(:build_infos) { create_list(:package_build_info, 5, :with_pipeline, package: package) }
+ let_it_be(:build_info_with_empty_pipeline) { create(:package_build_info, package: package) }
+
+ let_it_be(:other_package) { create(:package) }
+ let_it_be(:other_build_infos) { create_list(:package_build_info, 5, :with_pipeline, package: other_package) }
+ let_it_be(:other_build_info_with_empty_pipeline) { create(:package_build_info, package: other_package) }
+
+ let_it_be(:all_build_infos) { build_infos + other_build_infos }
+
+ let(:finder) { described_class.new(packages, params) }
+ let(:packages) { nil }
+ let(:first) { nil }
+ let(:last) { nil }
+ let(:after) { nil }
+ let(:before) { nil }
+ let(:max_page_size) { nil }
+ let(:support_next_page) { false }
+ let(:params) do
+ {
+ first: first,
+ last: last,
+ after: after,
+ before: before,
+ max_page_size: max_page_size,
+ support_next_page: support_next_page
+ }
+ end
+
+ describe '#execute' do
+ subject { finder.execute }
+
+ shared_examples 'returning the expected build infos' do
+ let(:expected_build_infos) do
+ expected_build_infos_indexes.map do |idx|
+ all_build_infos[idx]
+ end
+ end
+
+ let(:after) do
+ all_build_infos[after_index].pipeline_id if after_index
+ end
+
+ let(:before) do
+ all_build_infos[before_index].pipeline_id if before_index
+ end
+
+ it { is_expected.to eq(expected_build_infos) }
+ end
+
+ context 'with nil packages' do
+ let(:packages) { nil }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'with [] packages' do
+ let(:packages) { [] }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'with empy scope packages' do
+ let(:packages) { Packages::Package.none }
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'with a single package' do
+ let(:packages) { package.id }
+
+ # rubocop: disable Layout/LineLength
+ where(:first, :last, :after_index, :before_index, :max_page_size, :support_next_page, :expected_build_infos_indexes) do
+ # F L AI BI MPS SNP
+ nil | nil | nil | nil | nil | false | [4, 3, 2, 1, 0]
+ nil | nil | nil | nil | 10 | false | [4, 3, 2, 1, 0]
+ nil | nil | nil | nil | 2 | false | [4, 3]
+ 2 | nil | nil | nil | nil | false | [4, 3]
+ 2 | nil | nil | nil | nil | true | [4, 3, 2]
+ 2 | nil | 3 | nil | nil | false | [2, 1]
+ 2 | nil | 3 | nil | nil | true | [2, 1, 0]
+ 3 | nil | 4 | nil | 2 | false | [3, 2]
+ 3 | nil | 4 | nil | 2 | true | [3, 2, 1]
+ nil | 2 | nil | nil | nil | false | [1, 0]
+ nil | 2 | nil | nil | nil | true | [2, 1, 0]
+ nil | 2 | nil | 1 | nil | false | [3, 2]
+ nil | 2 | nil | 1 | nil | true | [4, 3, 2]
+ nil | 3 | nil | 0 | 2 | false | [2, 1]
+ nil | 3 | nil | 0 | 2 | true | [3, 2, 1]
+ end
+ # rubocop: enable Layout/LineLength
+
+ with_them do
+ it_behaves_like 'returning the expected build infos'
+ end
+ end
+
+ context 'with many packages' do
+ let(:packages) { [package.id, other_package.id] }
+
+ # using after_index/before_index when receiving multiple packages doesn't
+ # make sense but we still verify here that the behavior is coherent.
+ # rubocop: disable Layout/LineLength
+ where(:first, :last, :after_index, :before_index, :max_page_size, :support_next_page, :expected_build_infos_indexes) do
+ # F L AI BI MPS SNP
+ nil | nil | nil | nil | nil | false | [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
+ nil | nil | nil | nil | 10 | false | [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
+ nil | nil | nil | nil | 2 | false | [9, 8, 4, 3]
+ 2 | nil | nil | nil | nil | false | [9, 8, 4, 3]
+ 2 | nil | nil | nil | nil | true | [9, 8, 7, 4, 3, 2]
+ 2 | nil | 3 | nil | nil | false | [2, 1]
+ 2 | nil | 3 | nil | nil | true | [2, 1, 0]
+ 3 | nil | 4 | nil | 2 | false | [3, 2]
+ 3 | nil | 4 | nil | 2 | true | [3, 2, 1]
+ nil | 2 | nil | nil | nil | false | [6, 5, 1, 0]
+ nil | 2 | nil | nil | nil | true | [7, 6, 5, 2, 1, 0]
+ nil | 2 | nil | 1 | nil | false | [6, 5, 3, 2]
+ nil | 2 | nil | 1 | nil | true | [7, 6, 5, 4, 3, 2]
+ nil | 3 | nil | 0 | 2 | false | [6, 5, 2, 1]
+ nil | 3 | nil | 0 | 2 | true | [7, 6, 5, 3, 2, 1]
+ end
+
+ with_them do
+ it_behaves_like 'returning the expected build infos'
+ end
+ # rubocop: enable Layout/LineLength
+ end
+ end
+end
diff --git a/spec/finders/packages/group_packages_finder_spec.rb b/spec/finders/packages/group_packages_finder_spec.rb
index c2dbfb59eb2..954db6481cd 100644
--- a/spec/finders/packages/group_packages_finder_spec.rb
+++ b/spec/finders/packages/group_packages_finder_spec.rb
@@ -149,6 +149,22 @@ RSpec.describe Packages::GroupPackagesFinder do
it { is_expected.to match_array([package1, package2]) }
end
+ context 'preload_pipelines' do
+ it 'preloads pipelines by default' do
+ expect(Packages::Package).to receive(:preload_pipelines).and_call_original
+ expect(subject).to match_array([package1, package2])
+ end
+
+ context 'set to false' do
+ let(:params) { { preload_pipelines: false } }
+
+ it 'does not preload pipelines' do
+ expect(Packages::Package).not_to receive(:preload_pipelines)
+ expect(subject).to match_array([package1, package2])
+ end
+ end
+ end
+
context 'with package_name' do
let_it_be(:named_package) { create(:maven_package, project: project, name: 'maven') }
diff --git a/spec/finders/packages/packages_finder_spec.rb b/spec/finders/packages/packages_finder_spec.rb
index b72f4aab3ec..6cea0a44541 100644
--- a/spec/finders/packages/packages_finder_spec.rb
+++ b/spec/finders/packages/packages_finder_spec.rb
@@ -81,6 +81,22 @@ RSpec.describe ::Packages::PackagesFinder do
it { is_expected.to match_array([conan_package, maven_package]) }
end
+ context 'preload_pipelines' do
+ it 'preloads pipelines by default' do
+ expect(Packages::Package).to receive(:preload_pipelines).and_call_original
+ expect(subject).to match_array([maven_package, conan_package])
+ end
+
+ context 'set to false' do
+ let(:params) { { preload_pipelines: false } }
+
+ it 'does not preload pipelines' do
+ expect(Packages::Package).not_to receive(:preload_pipelines)
+ expect(subject).to match_array([maven_package, conan_package])
+ end
+ end
+ end
+
it_behaves_like 'concerning versionless param'
it_behaves_like 'concerning package statuses'
end
diff --git a/spec/finders/releases/group_releases_finder_spec.rb b/spec/finders/releases/group_releases_finder_spec.rb
index b8899a8ee40..5eac6f4fbdc 100644
--- a/spec/finders/releases/group_releases_finder_spec.rb
+++ b/spec/finders/releases/group_releases_finder_spec.rb
@@ -95,8 +95,6 @@ RSpec.describe Releases::GroupReleasesFinder do
end
describe 'with subgroups' do
- let(:params) { { include_subgroups: true } }
-
subject(:releases) { described_class.new(group, user, params).execute(**args) }
context 'with a single-level subgroup' do
@@ -164,22 +162,12 @@ RSpec.describe Releases::GroupReleasesFinder do
end
end
- context 'when the user a guest on the group' do
- before do
- group.add_guest(user)
- end
-
- it 'returns all releases' do
- expect(releases).to match_array([v1_1_1, v1_1_0, v6, v1_0_0, p3])
- end
- end
-
context 'performance testing' do
shared_examples 'avoids N+1 queries' do |query_params = {}|
context 'with subgroups' do
let(:params) { query_params }
- it 'include_subgroups avoids N+1 queries' do
+ it 'subgroups avoids N+1 queries' do
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
releases
end.count
@@ -196,7 +184,6 @@ RSpec.describe Releases::GroupReleasesFinder do
end
it_behaves_like 'avoids N+1 queries'
- it_behaves_like 'avoids N+1 queries', { simple: true }
end
end
end
diff --git a/spec/finders/user_recent_events_finder_spec.rb b/spec/finders/user_recent_events_finder_spec.rb
index 6019d22059d..d7f7bb9cebe 100644
--- a/spec/finders/user_recent_events_finder_spec.rb
+++ b/spec/finders/user_recent_events_finder_spec.rb
@@ -8,9 +8,9 @@ RSpec.describe UserRecentEventsFinder do
let_it_be(:private_project) { create(:project, :private, creator: project_owner) }
let_it_be(:internal_project) { create(:project, :internal, creator: project_owner) }
let_it_be(:public_project) { create(:project, :public, creator: project_owner) }
- let!(:private_event) { create(:event, project: private_project, author: project_owner) }
- let!(:internal_event) { create(:event, project: internal_project, author: project_owner) }
- let!(:public_event) { create(:event, project: public_project, author: project_owner) }
+ let_it_be(:private_event) { create(:event, project: private_project, author: project_owner) }
+ let_it_be(:internal_event) { create(:event, project: internal_project, author: project_owner) }
+ let_it_be(:public_event) { create(:event, project: public_project, author: project_owner) }
let_it_be(:issue) { create(:issue, project: public_project) }
let(:limit) { nil }
@@ -18,210 +18,266 @@ RSpec.describe UserRecentEventsFinder do
subject(:finder) { described_class.new(current_user, project_owner, nil, params) }
- describe '#execute' do
- context 'when profile is public' do
- it 'returns all the events' do
- expect(finder.execute).to include(private_event, internal_event, public_event)
+ shared_examples 'UserRecentEventsFinder examples' do
+ describe '#execute' do
+ context 'when profile is public' do
+ it 'returns all the events' do
+ expect(finder.execute).to include(private_event, internal_event, public_event)
+ end
end
- end
- context 'when profile is private' do
- it 'returns no event' do
- allow(Ability).to receive(:allowed?).and_call_original
- allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, project_owner).and_return(false)
+ context 'when profile is private' do
+ it 'returns no event' do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, project_owner).and_return(false)
- expect(finder.execute).to be_empty
+ expect(finder.execute).to be_empty
+ end
end
- end
- it 'does not include the events if the user cannot read cross project' do
- allow(Ability).to receive(:allowed?).and_call_original
- expect(Ability).to receive(:allowed?).with(current_user, :read_cross_project) { false }
+ it 'does not include the events if the user cannot read cross project' do
+ allow(Ability).to receive(:allowed?).and_call_original
+ expect(Ability).to receive(:allowed?).with(current_user, :read_cross_project) { false }
- expect(finder.execute).to be_empty
- end
+ expect(finder.execute).to be_empty
+ end
- context 'events from multiple users' do
- let_it_be(:second_user, reload: true) { create(:user) }
- let_it_be(:private_project_second_user) { create(:project, :private, creator: second_user) }
+ context 'events from multiple users' do
+ let_it_be(:second_user, reload: true) { create(:user) }
+ let_it_be(:private_project_second_user) { create(:project, :private, creator: second_user) }
- let(:internal_project_second_user) { create(:project, :internal, creator: second_user) }
- let(:public_project_second_user) { create(:project, :public, creator: second_user) }
- let!(:private_event_second_user) { create(:event, project: private_project_second_user, author: second_user) }
- let!(:internal_event_second_user) { create(:event, project: internal_project_second_user, author: second_user) }
- let!(:public_event_second_user) { create(:event, project: public_project_second_user, author: second_user) }
+ let_it_be(:internal_project_second_user) { create(:project, :internal, creator: second_user) }
+ let_it_be(:public_project_second_user) { create(:project, :public, creator: second_user) }
+ let_it_be(:private_event_second_user) { create(:event, project: private_project_second_user, author: second_user) }
+ let_it_be(:internal_event_second_user) { create(:event, project: internal_project_second_user, author: second_user) }
+ let_it_be(:public_event_second_user) { create(:event, project: public_project_second_user, author: second_user) }
- it 'includes events from all users', :aggregate_failures do
- events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
+ it 'includes events from all users', :aggregate_failures do
+ events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
- expect(events).to include(private_event, internal_event, public_event)
- expect(events).to include(private_event_second_user, internal_event_second_user, public_event_second_user)
- expect(events.size).to eq(6)
- end
+ expect(events).to include(private_event, internal_event, public_event)
+ expect(events).to include(private_event_second_user, internal_event_second_user, public_event_second_user)
+ expect(events.size).to eq(6)
+ end
- context 'selected events' do
- let!(:push_event) { create(:push_event, project: public_project, author: project_owner) }
- let!(:push_event_second_user) { create(:push_event, project: public_project_second_user, author: second_user) }
+ context 'selected events' do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:push_event1) { create(:push_event, project: public_project, author: project_owner) }
+ let_it_be(:push_event2) { create(:push_event, project: public_project_second_user, author: second_user) }
+ let_it_be(:merge_event1) { create(:event, :merged, target_type: MergeRequest.to_s, project: public_project, author: project_owner) }
+ let_it_be(:merge_event2) { create(:event, :merged, target_type: MergeRequest.to_s, project: public_project_second_user, author: second_user) }
+ let_it_be(:comment_event1) { create(:event, :commented, target_type: Note.to_s, project: public_project, author: project_owner) }
+ let_it_be(:comment_event2) { create(:event, :commented, target_type: DiffNote.to_s, project: public_project, author: project_owner) }
+ let_it_be(:comment_event3) { create(:event, :commented, target_type: DiscussionNote.to_s, project: public_project_second_user, author: second_user) }
+ let_it_be(:issue_event1) { create(:event, :created, project: public_project, target: issue, author: project_owner) }
+ let_it_be(:issue_event2) { create(:event, :updated, project: public_project, target: issue, author: project_owner) }
+ let_it_be(:issue_event3) { create(:event, :closed, project: public_project_second_user, target: issue, author: second_user) }
+ let_it_be(:wiki_event1) { create(:wiki_page_event, project: public_project, author: project_owner) }
+ let_it_be(:wiki_event2) { create(:wiki_page_event, project: public_project_second_user, author: second_user) }
+ let_it_be(:design_event1) { create(:design_event, project: public_project, author: project_owner) }
+ let_it_be(:design_event2) { create(:design_updated_event, project: public_project_second_user, author: second_user) }
+
+ where(:event_filter, :ordered_expected_events) do
+ EventFilter.new(EventFilter::PUSH) | lazy { [push_event1, push_event2] }
+ EventFilter.new(EventFilter::MERGED) | lazy { [merge_event1, merge_event2] }
+ EventFilter.new(EventFilter::COMMENTS) | lazy { [comment_event1, comment_event2, comment_event3] }
+ EventFilter.new(EventFilter::TEAM) | lazy { [private_event, internal_event, public_event, private_event_second_user, internal_event_second_user, public_event_second_user] }
+ EventFilter.new(EventFilter::ISSUE) | lazy { [issue_event1, issue_event2, issue_event3] }
+ EventFilter.new(EventFilter::WIKI) | lazy { [wiki_event1, wiki_event2] }
+ EventFilter.new(EventFilter::DESIGNS) | lazy { [design_event1, design_event2] }
+ end
- it 'only includes selected events (PUSH) from all users', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::PUSH)
- events = described_class.new(current_user, [project_owner, second_user], event_filter, params).execute
+ with_them do
+ it 'only returns selected events from all users (id DESC)' do
+ events = described_class.new(current_user, [project_owner, second_user], event_filter, params).execute
- expect(events).to contain_exactly(push_event, push_event_second_user)
+ expect(events).to eq(ordered_expected_events.reverse)
+ end
+ end
end
- end
- it 'does not include events from users with private profile', :aggregate_failures do
- allow(Ability).to receive(:allowed?).and_call_original
- allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, second_user).and_return(false)
+ it 'does not include events from users with private profile', :aggregate_failures do
+ allow(Ability).to receive(:allowed?).and_call_original
+ allow(Ability).to receive(:allowed?).with(current_user, :read_user_profile, second_user).and_return(false)
- events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
+ events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
- expect(events).to contain_exactly(private_event, internal_event, public_event)
- end
+ expect(events).to contain_exactly(private_event, internal_event, public_event)
+ end
- context 'with pagination params' do
- using RSpec::Parameterized::TableSyntax
+ context 'with pagination params' do
+ using RSpec::Parameterized::TableSyntax
- where(:limit, :offset, :ordered_expected_events) do
- nil | nil | lazy { [public_event_second_user, internal_event_second_user, private_event_second_user, public_event, internal_event, private_event] }
- 2 | nil | lazy { [public_event_second_user, internal_event_second_user] }
- nil | 4 | lazy { [internal_event, private_event] }
- 2 | 2 | lazy { [private_event_second_user, public_event] }
- end
+ where(:limit, :offset, :ordered_expected_events) do
+ nil | nil | lazy { [public_event_second_user, internal_event_second_user, private_event_second_user, public_event, internal_event, private_event] }
+ 2 | nil | lazy { [public_event_second_user, internal_event_second_user] }
+ nil | 4 | lazy { [internal_event, private_event] }
+ 2 | 2 | lazy { [private_event_second_user, public_event] }
+ end
- with_them do
- let(:params) { { limit: limit, offset: offset }.compact }
+ with_them do
+ let(:params) { { limit: limit, offset: offset }.compact }
- it 'returns paginated events sorted by id (DESC)' do
- events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
+ it 'returns paginated events sorted by id (DESC)' do
+ events = described_class.new(current_user, [project_owner, second_user], nil, params).execute
- expect(events).to eq(ordered_expected_events)
+ expect(events).to eq(ordered_expected_events)
+ end
end
end
end
- end
- context 'filter activity events' do
- let!(:push_event) { create(:push_event, project: public_project, author: project_owner) }
- let!(:merge_event) { create(:event, :merged, project: public_project, author: project_owner) }
- let!(:issue_event) { create(:event, :closed, project: public_project, target: issue, author: project_owner) }
- let!(:comment_event) { create(:event, :commented, project: public_project, author: project_owner) }
- let!(:wiki_event) { create(:wiki_page_event, project: public_project, author: project_owner) }
- let!(:design_event) { create(:design_event, project: public_project, author: project_owner) }
- let!(:team_event) { create(:event, :joined, project: public_project, author: project_owner) }
-
- it 'includes all events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::ALL)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
-
- expect(events).to include(private_event, internal_event, public_event)
- expect(events).to include(push_event, merge_event, issue_event, comment_event, wiki_event, design_event, team_event)
- expect(events.size).to eq(10)
- end
+ context 'filter activity events' do
+ let_it_be(:push_event) { create(:push_event, project: public_project, author: project_owner) }
+ let_it_be(:merge_event) { create(:event, :merged, project: public_project, author: project_owner) }
+ let_it_be(:issue_event) { create(:event, :closed, project: public_project, target: issue, author: project_owner) }
+ let_it_be(:comment_event) { create(:event, :commented, project: public_project, author: project_owner) }
+ let_it_be(:wiki_event) { create(:wiki_page_event, project: public_project, author: project_owner) }
+ let_it_be(:design_event) { create(:design_event, project: public_project, author: project_owner) }
+ let_it_be(:team_event) { create(:event, :joined, project: public_project, author: project_owner) }
+
+ it 'includes all events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::ALL)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
+
+ expect(events).to include(private_event, internal_event, public_event)
+ expect(events).to include(push_event, merge_event, issue_event, comment_event, wiki_event, design_event, team_event)
+ expect(events.size).to eq(10)
+ end
- it 'only includes push events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::PUSH)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
+ context 'when unknown filter is given' do
+ it 'includes returns all events', :aggregate_failures do
+ event_filter = EventFilter.new('unknown')
+ allow(event_filter).to receive(:filter).and_return('unknown')
- expect(events).to include(push_event)
- expect(events.size).to eq(1)
- end
+ events = described_class.new(current_user, [project_owner], event_filter, params).execute
- it 'only includes merge events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::MERGED)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
+ expect(events).to include(private_event, internal_event, public_event)
+ expect(events).to include(push_event, merge_event, issue_event, comment_event, wiki_event, design_event, team_event)
+ expect(events.size).to eq(10)
+ end
+ end
- expect(events).to include(merge_event)
- expect(events.size).to eq(1)
- end
+ it 'only includes push events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::PUSH)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
- it 'only includes issue events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::ISSUE)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
+ expect(events).to include(push_event)
+ expect(events.size).to eq(1)
+ end
- expect(events).to include(issue_event)
- expect(events.size).to eq(1)
- end
+ it 'only includes merge events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::MERGED)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
- it 'only includes comments events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::COMMENTS)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
+ expect(events).to include(merge_event)
+ expect(events.size).to eq(1)
+ end
- expect(events).to include(comment_event)
- expect(events.size).to eq(1)
- end
+ it 'only includes issue events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::ISSUE)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
- it 'only includes wiki events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::WIKI)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
+ expect(events).to include(issue_event)
+ expect(events.size).to eq(1)
+ end
- expect(events).to include(wiki_event)
- expect(events.size).to eq(1)
- end
+ it 'only includes comments events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::COMMENTS)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
- it 'only includes design events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::DESIGNS)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
+ expect(events).to include(comment_event)
+ expect(events.size).to eq(1)
+ end
- expect(events).to include(design_event)
- expect(events.size).to eq(1)
- end
+ it 'only includes wiki events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::WIKI)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
- it 'only includes team events', :aggregate_failures do
- event_filter = EventFilter.new(EventFilter::TEAM)
- events = described_class.new(current_user, project_owner, event_filter, params).execute
+ expect(events).to include(wiki_event)
+ expect(events.size).to eq(1)
+ end
- expect(events).to include(private_event, internal_event, public_event, team_event)
- expect(events.size).to eq(4)
- end
- end
+ it 'only includes design events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::DESIGNS)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
- describe 'issue activity events' do
- let(:issue) { create(:issue, project: public_project) }
- let(:note) { create(:note_on_issue, noteable: issue, project: public_project) }
- let!(:event_a) { create(:event, :commented, target: note, author: project_owner) }
- let!(:event_b) { create(:event, :closed, target: issue, author: project_owner) }
+ expect(events).to include(design_event)
+ expect(events.size).to eq(1)
+ end
- it 'includes all issue related events', :aggregate_failures do
- events = finder.execute
+ it 'only includes team events', :aggregate_failures do
+ event_filter = EventFilter.new(EventFilter::TEAM)
+ events = described_class.new(current_user, project_owner, event_filter, params).execute
- expect(events).to include(event_a)
- expect(events).to include(event_b)
+ expect(events).to include(private_event, internal_event, public_event, team_event)
+ expect(events.size).to eq(4)
+ end
end
- end
- context 'limits' do
- before do
- stub_const("#{described_class}::DEFAULT_LIMIT", 1)
- stub_const("#{described_class}::MAX_LIMIT", 3)
- end
+ describe 'issue activity events' do
+ let(:issue) { create(:issue, project: public_project) }
+ let(:note) { create(:note_on_issue, noteable: issue, project: public_project) }
+ let!(:event_a) { create(:event, :commented, target: note, author: project_owner) }
+ let!(:event_b) { create(:event, :closed, target: issue, author: project_owner) }
- context 'when limit is not set' do
- it 'returns events limited to DEFAULT_LIMIT' do
- expect(finder.execute.size).to eq(described_class::DEFAULT_LIMIT)
+ it 'includes all issue related events', :aggregate_failures do
+ events = finder.execute
+
+ expect(events).to include(event_a)
+ expect(events).to include(event_b)
end
end
- context 'when limit is set' do
- let(:limit) { 2 }
+ context 'limits' do
+ before do
+ stub_const("#{described_class}::DEFAULT_LIMIT", 1)
+ stub_const("#{described_class}::MAX_LIMIT", 3)
+ end
- it 'returns events limited to specified limit' do
- expect(finder.execute.size).to eq(limit)
+ context 'when limit is not set' do
+ it 'returns events limited to DEFAULT_LIMIT' do
+ expect(finder.execute.size).to eq(described_class::DEFAULT_LIMIT)
+ end
end
- end
- context 'when limit is set to a number that exceeds maximum limit' do
- let(:limit) { 4 }
+ context 'when limit is set' do
+ let(:limit) { 2 }
- before do
- create(:event, project: public_project, author: project_owner)
+ it 'returns events limited to specified limit' do
+ expect(finder.execute.size).to eq(limit)
+ end
end
- it 'returns events limited to MAX_LIMIT' do
- expect(finder.execute.size).to eq(described_class::MAX_LIMIT)
+ context 'when limit is set to a number that exceeds maximum limit' do
+ let(:limit) { 4 }
+
+ before do
+ create(:event, project: public_project, author: project_owner)
+ end
+
+ it 'returns events limited to MAX_LIMIT' do
+ expect(finder.execute.size).to eq(described_class::MAX_LIMIT)
+ end
end
end
end
end
+
+ context 'when the optimized_followed_users_queries FF is on' do
+ before do
+ stub_feature_flags(optimized_followed_users_queries: true)
+ end
+
+ it_behaves_like 'UserRecentEventsFinder examples'
+ end
+
+ context 'when the optimized_followed_users_queries FF is off' do
+ before do
+ stub_feature_flags(optimized_followed_users_queries: false)
+ end
+
+ it_behaves_like 'UserRecentEventsFinder examples'
+ end
end
diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb
index fab48cf3178..271dce44db7 100644
--- a/spec/finders/users_finder_spec.rb
+++ b/spec/finders/users_finder_spec.rb
@@ -6,13 +6,15 @@ RSpec.describe UsersFinder do
describe '#execute' do
include_context 'UsersFinder#execute filter by project context'
+ let_it_be(:project_bot) { create(:user, :project_bot) }
+
context 'with a normal user' do
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
- it 'returns all users' do
+ it 'returns searchable users' do
users = described_class.new(user).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, external_user, omniauth_user, internal_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, external_user, unconfirmed_user, omniauth_user, internal_user, admin_user, project_bot)
end
it 'filters by username' do
@@ -34,9 +36,9 @@ RSpec.describe UsersFinder do
end
it 'filters by search' do
- users = described_class.new(user, search: 'orando').execute
+ users = described_class.new(user, search: 'ohndo').execute
- expect(users).to contain_exactly(blocked_user)
+ expect(users).to contain_exactly(normal_user)
end
it 'does not filter by private emails search' do
@@ -45,18 +47,6 @@ RSpec.describe UsersFinder do
expect(users).to be_empty
end
- it 'filters by blocked users' do
- 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(user, active: true).execute
-
- expect(users).to contain_exactly(user, normal_user, external_user, omniauth_user, admin_user)
- end
-
it 'filters by external users' do
users = described_class.new(user, external: true).execute
@@ -66,7 +56,7 @@ RSpec.describe UsersFinder do
it 'filters by non external users' do
users = described_class.new(user, non_external: true).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, omniauth_user, internal_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, unconfirmed_user, omniauth_user, internal_user, admin_user, project_bot)
end
it 'filters by created_at' do
@@ -83,7 +73,7 @@ RSpec.describe UsersFinder do
it 'filters by non internal users' do
users = described_class.new(user, non_internal: true).execute
- expect(users).to contain_exactly(user, normal_user, external_user, blocked_user, omniauth_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, unconfirmed_user, external_user, omniauth_user, admin_user, project_bot)
end
it 'does not filter by custom attributes' do
@@ -92,23 +82,23 @@ RSpec.describe UsersFinder do
custom_attributes: { foo: 'bar' }
).execute
- expect(users).to contain_exactly(user, normal_user, blocked_user, external_user, omniauth_user, internal_user, admin_user)
+ expect(users).to contain_exactly(user, normal_user, external_user, unconfirmed_user, omniauth_user, internal_user, admin_user, project_bot)
end
it 'orders returned results' do
users = described_class.new(user, sort: 'id_asc').execute
- expect(users).to eq([normal_user, admin_user, blocked_user, external_user, omniauth_user, internal_user, user])
+ expect(users).to eq([normal_user, admin_user, external_user, unconfirmed_user, omniauth_user, internal_user, project_bot, user])
end
it 'does not filter by admins' do
users = described_class.new(user, admins: true).execute
- expect(users).to contain_exactly(user, normal_user, external_user, admin_user, blocked_user, omniauth_user, internal_user)
+ expect(users).to contain_exactly(user, normal_user, external_user, admin_user, unconfirmed_user, omniauth_user, internal_user, project_bot)
end
end
context 'with an admin user', :enable_admin_mode do
- let(:admin) { create(:admin) }
+ let_it_be(:admin) { create(:admin) }
it 'filters by external users' do
users = described_class.new(admin, external: true).execute
@@ -119,7 +109,19 @@ RSpec.describe UsersFinder do
it 'returns all users' do
users = described_class.new(admin).execute
- expect(users).to contain_exactly(admin, normal_user, blocked_user, external_user, omniauth_user, internal_user, admin_user)
+ expect(users).to contain_exactly(admin, 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
+
+ expect(users).to contain_exactly(blocked_user)
+ end
+
+ it 'filters by active users' do
+ users = described_class.new(admin, active: true).execute
+
+ expect(users).to contain_exactly(admin, normal_user, unconfirmed_user, external_user, omniauth_user, admin_user, project_bot)
end
it 'returns only admins' do