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>2023-12-19 14:01:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-12-19 14:01:45 +0300
commit9297025d0b7ddf095eb618dfaaab2ff8f2018d8b (patch)
tree865198c01d1824a9b098127baa3ab980c9cd2c06 /spec/models/ci/catalog/listing_spec.rb
parent6372471f43ee03c05a7c1f8b0c6ac6b8a7431dbe (diff)
Add latest changes from gitlab-org/gitlab@16-7-stable-eev16.7.0-rc42
Diffstat (limited to 'spec/models/ci/catalog/listing_spec.rb')
-rw-r--r--spec/models/ci/catalog/listing_spec.rb292
1 files changed, 187 insertions, 105 deletions
diff --git a/spec/models/ci/catalog/listing_spec.rb b/spec/models/ci/catalog/listing_spec.rb
index 7a1e12165ac..2ffffb9112c 100644
--- a/spec/models/ci/catalog/listing_spec.rb
+++ b/spec/models/ci/catalog/listing_spec.rb
@@ -3,59 +3,61 @@
require 'spec_helper'
RSpec.describe Ci::Catalog::Listing, feature_category: :pipeline_composition do
- let_it_be(:namespace) { create(:group) }
- let_it_be(:project_x) { create(:project, namespace: namespace, name: 'X Project') }
- let_it_be(:project_a) { create(:project, :public, namespace: namespace, name: 'A Project') }
- let_it_be(:project_noaccess) { create(:project, namespace: namespace, name: 'C Project') }
- let_it_be(:project_ext) { create(:project, :public, name: 'TestProject') }
let_it_be(:user) { create(:user) }
+ let_it_be(:namespace) { create(:group) }
+ let_it_be(:public_namespace_project) do
+ create(:project, :public, namespace: namespace, name: 'A public namespace project')
+ end
- let_it_be(:project_b) do
+ let_it_be(:public_project) { create(:project, :public, name: 'B public test project') }
+ let_it_be(:namespace_project_a) { create(:project, namespace: namespace, name: 'Test namespace project') }
+ let_it_be(:namespace_project_b) { create(:project, namespace: namespace, name: 'X namespace Project') }
+ let_it_be(:project_noaccess) { create(:project, namespace: namespace, name: 'Project with no access') }
+ let_it_be(:internal_project) { create(:project, :internal, name: 'Internal project') }
+
+ let_it_be(:private_project) do
create(:project, namespace: namespace, name: 'B Project', description: 'Rspec test framework')
end
let(:list) { described_class.new(user) }
before_all do
- project_x.add_reporter(user)
- project_b.add_reporter(user)
- project_a.add_reporter(user)
- project_ext.add_reporter(user)
+ namespace_project_a.add_reporter(user)
+ namespace_project_b.add_reporter(user)
+ public_namespace_project.add_reporter(user)
+ public_project.add_reporter(user)
+ internal_project.add_owner(user)
end
describe '#resources' do
subject(:resources) { list.resources(**params) }
- context 'when user is anonymous' do
- let(:user) { nil }
- let(:params) { {} }
+ let(:params) { {} }
- let!(:resource_1) { create(:ci_catalog_resource, project: project_a) }
- let!(:resource_2) { create(:ci_catalog_resource, project: project_ext) }
- let!(:resource_3) { create(:ci_catalog_resource, project: project_b) }
+ let_it_be(:public_resource_a) { create(:ci_catalog_resource, :published, project: public_namespace_project) }
+ let_it_be(:public_resource_b) { create(:ci_catalog_resource, :published, project: public_project) }
+ let_it_be(:internal_resource) { create(:ci_catalog_resource, :published, project: internal_project) }
+ let_it_be(:private_namespace_resource) { create(:ci_catalog_resource, :published, project: namespace_project_a) }
+ let_it_be(:unpublished_resource) { create(:ci_catalog_resource, project: namespace_project_b) }
- it 'returns only resources for public projects' do
- is_expected.to contain_exactly(resource_1, resource_2)
- end
+ it 'by default returns all resources visible to the current user' do
+ is_expected.to contain_exactly(public_resource_a, public_resource_b, private_namespace_resource,
+ internal_resource)
+ end
- context 'when sorting is provided' do
- let(:params) { { sort: :name_desc } }
+ context 'when user is anonymous' do
+ let(:user) { nil }
- it 'returns only resources for public projects sorted by name DESC' do
- is_expected.to contain_exactly(resource_2, resource_1)
- end
+ it 'returns only published resources for public projects' do
+ is_expected.to contain_exactly(public_resource_a, public_resource_b)
end
end
context 'when search params are provided' do
let(:params) { { search: 'test' } }
- let!(:resource_1) { create(:ci_catalog_resource, project: project_a) }
- let!(:resource_2) { create(:ci_catalog_resource, project: project_ext) }
- let!(:resource_3) { create(:ci_catalog_resource, project: project_b) }
-
it 'returns the resources that match the search params' do
- is_expected.to contain_exactly(resource_2, resource_3)
+ is_expected.to contain_exactly(public_resource_b, private_namespace_resource)
end
context 'when search term is too small' do
@@ -65,117 +67,197 @@ RSpec.describe Ci::Catalog::Listing, feature_category: :pipeline_composition do
end
end
- context 'when namespace is provided' do
- let(:params) { { namespace: namespace } }
+ context 'when the scope is :namespaces' do
+ let_it_be(:public_resource_no_namespace) do
+ create(:ci_catalog_resource, project: create(:project, :public, name: 'public'))
+ end
- context 'when namespace is not a root namespace' do
- let(:namespace) { create(:group, :nested) }
+ let(:params) { { scope: :namespaces } }
- it 'raises an exception' do
- expect { resources }.to raise_error(ArgumentError, 'Namespace is not a root namespace')
+ context 'when the `ci_guard_query_for_catalog_resource_scope` ff is enabled' do
+ it "returns the catalog resources belonging to the user's authorized namespaces" do
+ is_expected.to contain_exactly(public_resource_a, public_resource_b, internal_resource,
+ private_namespace_resource)
end
end
- context 'when the user has access to all projects in the namespace' do
- context 'when the namespace has no catalog resources' do
- it { is_expected.to be_empty }
+ context 'when the `ci_guard_query_for_catalog_resource_scope` ff is disabled' do
+ before do
+ stub_feature_flags(ci_guard_for_catalog_resource_scope: false)
end
- context 'when the namespace has catalog resources' do
- let_it_be(:today) { Time.zone.now }
- let_it_be(:yesterday) { today - 1.day }
- let_it_be(:tomorrow) { today + 1.day }
+ it 'returns all resources visible to the current user' do
+ is_expected.to contain_exactly(
+ public_resource_a, public_resource_b, private_namespace_resource,
+ internal_resource)
+ end
+ end
+ end
- let_it_be(:resource_1) do
- create(:ci_catalog_resource, project: project_x, latest_released_at: yesterday, created_at: today)
- end
+ context 'with a sort parameter' do
+ let_it_be(:today) { Time.zone.now }
+ let_it_be(:yesterday) { today - 1.day }
+ let_it_be(:tomorrow) { today + 1.day }
- let_it_be(:resource_2) do
- create(:ci_catalog_resource, project: project_b, latest_released_at: today, created_at: yesterday)
- end
+ let(:params) { { sort: sort } }
- let_it_be(:resource_3) do
- create(:ci_catalog_resource, project: project_a, latest_released_at: nil, created_at: tomorrow)
- end
+ before_all do
+ public_resource_a.update!(created_at: today, latest_released_at: yesterday)
+ public_resource_b.update!(created_at: yesterday, latest_released_at: today)
+ private_namespace_resource.update!(created_at: tomorrow, latest_released_at: tomorrow)
+ internal_resource.update!(created_at: tomorrow + 1)
+ end
- let_it_be(:other_namespace_resource) do
- create(:ci_catalog_resource, project: project_ext, latest_released_at: tomorrow)
- end
+ context 'when the sort is created_at ascending' do
+ let_it_be(:sort) { :created_at_asc }
+
+ it 'contains catalog resources sorted by created_at ascending' do
+ is_expected.to eq([public_resource_b, public_resource_a, private_namespace_resource, internal_resource])
+ end
+ end
+
+ context 'when the sort is created_at descending' do
+ let_it_be(:sort) { :created_at_desc }
+
+ it 'contains catalog resources sorted by created_at descending' do
+ is_expected.to eq([internal_resource, private_namespace_resource, public_resource_a, public_resource_b])
+ end
+ end
+
+ context 'when the sort is name ascending' do
+ let_it_be(:sort) { :name_asc }
+
+ it 'contains catalog resources for projects sorted by name ascending' do
+ is_expected.to eq([public_resource_a, public_resource_b, internal_resource, private_namespace_resource])
+ end
+ end
+
+ context 'when the sort is name descending' do
+ let_it_be(:sort) { :name_desc }
+
+ it 'contains catalog resources for projects sorted by name descending' do
+ is_expected.to eq([private_namespace_resource, internal_resource, public_resource_b, public_resource_a])
+ end
+ end
- it 'contains only catalog resources for projects in that namespace' do
- is_expected.to contain_exactly(resource_1, resource_2, resource_3)
+ context 'when the sort is latest_released_at ascending' do
+ let_it_be(:sort) { :latest_released_at_asc }
+
+ it 'contains catalog resources sorted by latest_released_at ascending with nulls last' do
+ is_expected.to eq([public_resource_a, public_resource_b, private_namespace_resource, internal_resource])
+ end
+ end
+
+ context 'when the sort is latest_released_at descending' do
+ let_it_be(:sort) { :latest_released_at_desc }
+
+ it 'contains catalog resources sorted by latest_released_at descending with nulls last' do
+ is_expected.to eq([private_namespace_resource, public_resource_b, public_resource_a, internal_resource])
+ end
+ end
+ end
+
+ context 'when namespace is provided' do
+ let(:params) { { namespace: namespace } }
+
+ context 'when it is a root namespace' do
+ context 'when it has catalog resources' do
+ it 'returns resources in the namespace visible to the user' do
+ is_expected.to contain_exactly(public_resource_a, private_namespace_resource)
end
+ end
- context 'with a sort parameter' do
- let(:params) { { namespace: namespace, sort: sort } }
+ context 'when the namespace has no catalog resources' do
+ let(:namespace) { build(:namespace) }
- context 'when the sort is created_at ascending' do
- let_it_be(:sort) { :created_at_asc }
+ it { is_expected.to be_empty }
+ end
+ end
- it 'contains catalog resources sorted by created_at ascending' do
- is_expected.to eq([resource_2, resource_1, resource_3])
- end
- end
+ context 'when namespace is not a root namespace' do
+ let_it_be(:namespace) { create(:group, :nested) }
- context 'when the sort is created_at descending' do
- let_it_be(:sort) { :created_at_desc }
+ it 'raises an exception' do
+ expect { resources }.to raise_error(ArgumentError, 'Namespace is not a root namespace')
+ end
+ end
+ end
+ end
- it 'contains catalog resources sorted by created_at descending' do
- is_expected.to eq([resource_3, resource_1, resource_2])
- end
- end
+ describe '#find_resource' do
+ let_it_be(:accessible_resource) { create(:ci_catalog_resource, :published, project: public_project) }
+ let_it_be(:inaccessible_resource) { create(:ci_catalog_resource, :published, project: project_noaccess) }
+ let_it_be(:draft_resource) { create(:ci_catalog_resource, project: public_namespace_project, state: :draft) }
- context 'when the sort is name ascending' do
- let_it_be(:sort) { :name_asc }
+ context 'when using the ID argument' do
+ subject { list.find_resource(id: id) }
- it 'contains catalog resources for projects sorted by name ascending' do
- is_expected.to eq([resource_3, resource_2, resource_1])
- end
- end
+ context 'when the resource is published and visible to the user' do
+ let(:id) { accessible_resource.id }
- context 'when the sort is name descending' do
- let_it_be(:sort) { :name_desc }
+ it 'fetches the resource' do
+ is_expected.to eq(accessible_resource)
+ end
+ end
- it 'contains catalog resources for projects sorted by name descending' do
- is_expected.to eq([resource_1, resource_2, resource_3])
- end
- end
+ context 'when the resource is not found' do
+ let(:id) { 'not-an-id' }
- context 'when the sort is latest_released_at ascending' do
- let_it_be(:sort) { :latest_released_at_asc }
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
- it 'contains catalog resources sorted by latest_released_at ascending with nulls last' do
- is_expected.to eq([resource_1, resource_2, resource_3])
- end
- end
+ context 'when the resource is not published' do
+ let(:id) { draft_resource.id }
- context 'when the sort is latest_released_at descending' do
- let_it_be(:sort) { :latest_released_at_desc }
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
- it 'contains catalog resources sorted by latest_released_at descending with nulls last' do
- is_expected.to eq([resource_2, resource_1, resource_3])
- end
- end
- end
+ context "when the current user cannot read code on the resource's project" do
+ let(:id) { inaccessible_resource.id }
+
+ it 'returns nil' do
+ is_expected.to be_nil
end
end
+ end
- context 'when the user only has access to some projects in the namespace' do
- let!(:accessible_resource) { create(:ci_catalog_resource, project: project_x) }
- let!(:inaccessible_resource) { create(:ci_catalog_resource, project: project_noaccess) }
+ context 'when using the full_path argument' do
+ subject { list.find_resource(full_path: full_path) }
- it 'only returns catalog resources for projects the user has access to' do
- is_expected.to contain_exactly(accessible_resource)
+ context 'when the resource is published and visible to the user' do
+ let(:full_path) { accessible_resource.project.full_path }
+
+ it 'fetches the resource' do
+ is_expected.to eq(accessible_resource)
end
end
- context 'when the user does not have access to the namespace' do
- let!(:project) { create(:project) }
- let!(:resource) { create(:ci_catalog_resource, project: project) }
+ context 'when the resource is not found' do
+ let(:full_path) { 'not-a-path' }
- let(:namespace) { project.namespace }
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
- it { is_expected.to be_empty }
+ context 'when the resource is not published' do
+ let(:full_path) { draft_resource.project.full_path }
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+
+ context "when the current user cannot read code on the resource's project" do
+ let(:full_path) { inaccessible_resource.project.full_path }
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
end
end
end