summaryrefslogtreecommitdiff
path: root/spec/requests/api/maven_packages_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/requests/api/maven_packages_spec.rb')
-rw-r--r--spec/requests/api/maven_packages_spec.rb426
1 files changed, 229 insertions, 197 deletions
diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb
index 4fc5fcf8282..d9f11b19e6e 100644
--- a/spec/requests/api/maven_packages_spec.rb
+++ b/spec/requests/api/maven_packages_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe API::MavenPackages do
include_context 'workhorse headers'
let_it_be_with_refind(:package_settings) { create(:namespace_package_setting, :group) }
- let_it_be(:group) { package_settings.namespace }
+ let_it_be_with_refind(:group) { package_settings.namespace }
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, :public, namespace: group) }
let_it_be(:package, reload: true) { create(:maven_package, project: project, name: project.full_path) }
@@ -15,12 +15,13 @@ RSpec.describe API::MavenPackages do
let_it_be(:package_file) { package.package_files.with_file_name_like('%.xml').first }
let_it_be(:jar_file) { package.package_files.with_file_name_like('%.jar').first }
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
- let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
+ let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token_for_group, group: group) }
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace, user: user } }
let(:package_name) { 'com/example/my-app' }
let(:headers) { workhorse_headers }
let(:headers_with_token) { headers.merge('Private-Token' => personal_access_token.token) }
@@ -39,22 +40,73 @@ RSpec.describe API::MavenPackages do
project.add_developer(user)
end
+ shared_examples 'handling groups and subgroups for' do |shared_example_name, visibilities: %i[public]|
+ context 'within a group' do
+ visibilities.each do |visibility|
+ context "that is #{visibility}" do
+ before do
+ group.update!(visibility_level: Gitlab::VisibilityLevel.level_value(visibility.to_s))
+ end
+
+ it_behaves_like shared_example_name
+ end
+ end
+ end
+
+ context 'within a subgroup' do
+ let_it_be_with_reload(:subgroup) { create(:group, parent: group) }
+
+ before do
+ move_project_to_namespace(subgroup)
+ end
+
+ visibilities.each do |visibility|
+ context "that is #{visibility}" do
+ before do
+ subgroup.update!(visibility_level: Gitlab::VisibilityLevel.level_value(visibility.to_s))
+ group.update!(visibility_level: Gitlab::VisibilityLevel.level_value(visibility.to_s))
+ end
+
+ it_behaves_like shared_example_name
+ end
+ end
+ end
+ end
+
+ shared_examples 'handling groups, subgroups and user namespaces for' do |shared_example_name, visibilities: %i[public]|
+ it_behaves_like 'handling groups and subgroups for', shared_example_name, visibilities: visibilities
+
+ context 'within a user namespace' do
+ before do
+ move_project_to_namespace(user.namespace)
+ end
+
+ visibilities.each do |visibility|
+ context "that is #{visibility}" do
+ before do
+ user.namespace.update!(visibility_level: Gitlab::VisibilityLevel.level_value(visibility.to_s))
+ end
+
+ it_behaves_like shared_example_name
+ end
+ end
+ end
+ end
+
shared_examples 'tracking the file download event' do
context 'with jar file' do
let_it_be(:package_file) { jar_file }
+ let(:snowplow_gitlab_standard_context) { { project: project, namespace: project.namespace } }
+
it_behaves_like 'a package tracking event', described_class.name, 'pull_package'
end
end
shared_examples 'rejecting the request for non existing maven path' do |expected_status: :not_found|
- before do
- if Feature.enabled?(:check_maven_path_first, default_enabled: :yaml)
- expect(::Packages::Maven::PackageFinder).not_to receive(:new)
- end
- end
-
it 'rejects the request' do
+ expect(::Packages::Maven::PackageFinder).not_to receive(:new)
+
subject
expect(response).to have_gitlab_http_status(expected_status)
@@ -166,10 +218,10 @@ RSpec.describe API::MavenPackages do
end
describe 'GET /api/v4/packages/maven/*path/:file_name' do
- shared_examples 'handling all conditions' do
- context 'a public project' do
- subject { download_file(file_name: package_file.file_name) }
+ context 'a public project' do
+ subject { download_file(file_name: package_file.file_name) }
+ shared_examples 'getting a file' do
it_behaves_like 'tracking the file download event'
it 'returns the file' do
@@ -194,14 +246,18 @@ RSpec.describe API::MavenPackages do
end
end
- context 'internal project' do
- before do
- project.team.truncate
- project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
- end
+ it_behaves_like 'handling groups, subgroups and user namespaces for', 'getting a file'
+ end
- subject { download_file_with_token(file_name: package_file.file_name) }
+ context 'internal project' do
+ before do
+ project.team.truncate
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ end
+ subject { download_file_with_token(file_name: package_file.file_name) }
+
+ shared_examples 'getting a file' do
it_behaves_like 'tracking the file download event'
it 'returns the file' do
@@ -228,13 +284,17 @@ RSpec.describe API::MavenPackages do
end
end
- context 'private project' do
- subject { download_file_with_token(file_name: package_file.file_name) }
+ it_behaves_like 'handling groups, subgroups and user namespaces for', 'getting a file', visibilities: %i[public internal]
+ end
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- end
+ context 'private project' do
+ subject { download_file_with_token(file_name: package_file.file_name) }
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ end
+
+ shared_examples 'getting a file' do
it_behaves_like 'tracking the file download event'
it 'returns the file' do
@@ -245,11 +305,13 @@ RSpec.describe API::MavenPackages do
end
it 'denies download when not enough permissions' do
- project.add_guest(user)
+ unless project.root_namespace == user.namespace
+ project.add_guest(user)
- subject
+ subject
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
end
it 'denies download when no private token' do
@@ -286,33 +348,19 @@ RSpec.describe API::MavenPackages do
end
end
- context 'project name is different from a package name' do
- before do
- maven_metadatum.update!(path: "wrong_name/#{package.version}")
- end
-
- it 'rejects request' do
- download_file(file_name: package_file.file_name)
-
- expect(response).to have_gitlab_http_status(:forbidden)
- end
- end
+ it_behaves_like 'handling groups, subgroups and user namespaces for', 'getting a file', visibilities: %i[public internal private]
end
- context 'with check_maven_path_first enabled' do
+ context 'project name is different from a package name' do
before do
- stub_feature_flags(check_maven_path_first: true)
+ maven_metadatum.update!(path: "wrong_name/#{package.version}")
end
- it_behaves_like 'handling all conditions'
- end
+ it 'rejects request' do
+ download_file(file_name: package_file.file_name)
- context 'with check_maven_path_first disabled' do
- before do
- stub_feature_flags(check_maven_path_first: false)
+ expect(response).to have_gitlab_http_status(:forbidden)
end
-
- it_behaves_like 'handling all conditions'
end
def download_file(file_name:, params: {}, request_headers: headers, path: maven_metadatum.path)
@@ -328,14 +376,16 @@ RSpec.describe API::MavenPackages do
let(:path) { package.maven_metadatum.path }
let(:url) { "/packages/maven/#{path}/#{package_file.file_name}" }
- it_behaves_like 'processing HEAD requests', instance_level: true
+ shared_examples 'heading a file' do
+ it_behaves_like 'processing HEAD requests', instance_level: true
+ end
context 'with check_maven_path_first enabled' do
before do
stub_feature_flags(check_maven_path_first: true)
end
- it_behaves_like 'processing HEAD requests', instance_level: true
+ it_behaves_like 'handling groups, subgroups and user namespaces for', 'heading a file'
end
context 'with check_maven_path_first disabled' do
@@ -343,7 +393,7 @@ RSpec.describe API::MavenPackages do
stub_feature_flags(check_maven_path_first: false)
end
- it_behaves_like 'processing HEAD requests', instance_level: true
+ it_behaves_like 'handling groups, subgroups and user namespaces for', 'heading a file'
end
end
@@ -353,10 +403,10 @@ RSpec.describe API::MavenPackages do
group.add_developer(user)
end
- shared_examples 'handling all conditions' do
- context 'a public project' do
- subject { download_file(file_name: package_file.file_name) }
+ context 'a public project' do
+ subject { download_file(file_name: package_file.file_name) }
+ shared_examples 'getting a file for a group' do
it_behaves_like 'tracking the file download event'
it 'returns the file' do
@@ -381,14 +431,18 @@ RSpec.describe API::MavenPackages do
end
end
- context 'internal project' do
- before do
- group.group_member(user).destroy!
- project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
- end
+ it_behaves_like 'handling groups and subgroups for', 'getting a file for a group'
+ end
+
+ context 'internal project' do
+ before do
+ group.group_member(user).destroy!
+ project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ end
- subject { download_file_with_token(file_name: package_file.file_name) }
+ subject { download_file_with_token(file_name: package_file.file_name) }
+ shared_examples 'getting a file for a group' do
it_behaves_like 'tracking the file download event'
it 'returns the file' do
@@ -415,13 +469,17 @@ RSpec.describe API::MavenPackages do
end
end
- context 'private project' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- end
+ it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: %i[internal public]
+ end
- subject { download_file_with_token(file_name: package_file.file_name) }
+ context 'private project' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ end
+
+ subject { download_file_with_token(file_name: package_file.file_name) }
+ shared_examples 'getting a file for a group' do
it_behaves_like 'tracking the file download event'
it 'returns the file' do
@@ -480,101 +538,87 @@ RSpec.describe API::MavenPackages do
it_behaves_like 'rejecting the request for non existing maven path'
end
end
+ end
- context 'with a reporter from a subgroup accessing the root group' do
- let_it_be(:root_group) { create(:group, :private) }
- let_it_be(:group) { create(:group, :private, parent: root_group) }
+ it_behaves_like 'handling groups and subgroups for', 'getting a file for a group', visibilities: %i[private internal public]
- subject { download_file_with_token(file_name: package_file.file_name, request_headers: headers_with_token, group_id: root_group.id) }
+ context 'with a reporter from a subgroup accessing the root group' do
+ let_it_be(:root_group) { create(:group, :private) }
+ let_it_be(:group) { create(:group, :private, parent: root_group) }
- before do
- project.update!(namespace: group)
- group.add_reporter(user)
- end
+ subject { download_file_with_token(file_name: package_file.file_name, request_headers: headers_with_token, group_id: root_group.id) }
- it 'returns the file' do
- subject
+ before do
+ project.update!(namespace: group)
+ group.add_reporter(user)
+ end
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('application/octet-stream')
- end
+ it 'returns the file' do
+ subject
- context 'with a non existing maven path' do
- subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3', request_headers: headers_with_token, group_id: root_group.id) }
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.media_type).to eq('application/octet-stream')
+ end
- it_behaves_like 'rejecting the request for non existing maven path'
- end
+ context 'with a non existing maven path' do
+ subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3', request_headers: headers_with_token, group_id: root_group.id) }
+
+ it_behaves_like 'rejecting the request for non existing maven path'
end
end
+ end
- context 'maven metadata file' do
- let_it_be(:sub_group1) { create(:group, parent: group) }
- let_it_be(:sub_group2) { create(:group, parent: group) }
- let_it_be(:project1) { create(:project, :private, group: sub_group1) }
- let_it_be(:project2) { create(:project, :private, group: sub_group2) }
- let_it_be(:project3) { create(:project, :private, group: sub_group1) }
- let_it_be(:package_name) { 'foo' }
- let_it_be(:package1) { create(:maven_package, project: project1, name: package_name, version: nil) }
- let_it_be(:package_file1) { create(:package_file, :xml, package: package1, file_name: 'maven-metadata.xml') }
- let_it_be(:package2) { create(:maven_package, project: project2, name: package_name, version: nil) }
- let_it_be(:package_file2) { create(:package_file, :xml, package: package2, file_name: 'maven-metadata.xml') }
- let_it_be(:package3) { create(:maven_package, project: project3, name: package_name, version: nil) }
- let_it_be(:package_file3) { create(:package_file, :xml, package: package3, file_name: 'maven-metadata.xml') }
+ context 'maven metadata file' do
+ let_it_be(:sub_group1) { create(:group, parent: group) }
+ let_it_be(:sub_group2) { create(:group, parent: group) }
+ let_it_be(:project1) { create(:project, :private, group: sub_group1) }
+ let_it_be(:project2) { create(:project, :private, group: sub_group2) }
+ let_it_be(:project3) { create(:project, :private, group: sub_group1) }
+ let_it_be(:package_name) { 'foo' }
+ let_it_be(:package1) { create(:maven_package, project: project1, name: package_name, version: nil) }
+ let_it_be(:package_file1) { create(:package_file, :xml, package: package1, file_name: 'maven-metadata.xml') }
+ let_it_be(:package2) { create(:maven_package, project: project2, name: package_name, version: nil) }
+ let_it_be(:package_file2) { create(:package_file, :xml, package: package2, file_name: 'maven-metadata.xml') }
+ let_it_be(:package3) { create(:maven_package, project: project3, name: package_name, version: nil) }
+ let_it_be(:package_file3) { create(:package_file, :xml, package: package3, file_name: 'maven-metadata.xml') }
- let(:maven_metadatum) { package3.maven_metadatum }
+ let(:maven_metadatum) { package3.maven_metadatum }
- subject { download_file_with_token(file_name: package_file3.file_name) }
+ subject { download_file_with_token(file_name: package_file3.file_name) }
- before do
- sub_group1.add_developer(user)
- sub_group2.add_developer(user)
- # the package with the most recently published file should be returned
- create(:package_file, :xml, package: package2)
- end
+ before do
+ sub_group1.add_developer(user)
+ sub_group2.add_developer(user)
+ # the package with the most recently published file should be returned
+ create(:package_file, :xml, package: package2)
+ end
- context 'in multiple versionless packages' do
- it 'downloads the file' do
- expect(::Packages::PackageFileFinder)
- .to receive(:new).with(package2, 'maven-metadata.xml').and_call_original
+ context 'in multiple versionless packages' do
+ it 'downloads the file' do
+ expect(::Packages::PackageFileFinder)
+ .to receive(:new).with(package2, 'maven-metadata.xml').and_call_original
- subject
- end
+ subject
end
+ end
- context 'in multiple snapshot packages' do
- before do
- version = '1.0.0-SNAPSHOT'
- [package1, package2, package3].each do |pkg|
- pkg.update!(version: version)
-
- pkg.maven_metadatum.update!(path: "#{pkg.name}/#{pkg.version}")
- end
- end
-
- it 'downloads the file' do
- expect(::Packages::PackageFileFinder)
- .to receive(:new).with(package3, 'maven-metadata.xml').and_call_original
+ context 'in multiple snapshot packages' do
+ before do
+ version = '1.0.0-SNAPSHOT'
+ [package1, package2, package3].each do |pkg|
+ pkg.update!(version: version)
- subject
+ pkg.maven_metadatum.update!(path: "#{pkg.name}/#{pkg.version}")
end
end
- end
- end
- context 'with check_maven_path_first enabled' do
- before do
- stub_feature_flags(check_maven_path_first: true)
- end
-
- it_behaves_like 'handling all conditions'
- end
+ it 'downloads the file' do
+ expect(::Packages::PackageFileFinder)
+ .to receive(:new).with(package3, 'maven-metadata.xml').and_call_original
- context 'with check_maven_path_first disabled' do
- before do
- stub_feature_flags(check_maven_path_first: false)
+ subject
+ end
end
-
- it_behaves_like 'handling all conditions'
end
def download_file(file_name:, params: {}, request_headers: headers, path: maven_metadatum.path, group_id: group.id)
@@ -595,7 +639,7 @@ RSpec.describe API::MavenPackages do
stub_feature_flags(check_maven_path_first: true)
end
- it_behaves_like 'processing HEAD requests'
+ it_behaves_like 'handling groups and subgroups for', 'processing HEAD requests'
end
context 'with check_maven_path_first disabled' do
@@ -603,95 +647,77 @@ RSpec.describe API::MavenPackages do
stub_feature_flags(check_maven_path_first: false)
end
- it_behaves_like 'processing HEAD requests'
+ it_behaves_like 'handling groups and subgroups for', 'processing HEAD requests'
end
end
describe 'GET /api/v4/projects/:id/packages/maven/*path/:file_name' do
- shared_examples 'handling all conditions' do
- context 'a public project' do
- subject { download_file(file_name: package_file.file_name) }
-
- it_behaves_like 'tracking the file download event'
-
- it 'returns the file' do
- subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('application/octet-stream')
- end
+ context 'a public project' do
+ subject { download_file(file_name: package_file.file_name) }
- it 'returns sha1 of the file' do
- download_file(file_name: package_file.file_name + '.sha1')
+ it_behaves_like 'tracking the file download event'
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('text/plain')
- expect(response.body).to eq(package_file.file_sha1)
- end
-
- context 'with a non existing maven path' do
- subject { download_file(file_name: package_file.file_name, path: 'foo/bar/1.2.3') }
+ it 'returns the file' do
+ subject
- it_behaves_like 'rejecting the request for non existing maven path'
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.media_type).to eq('application/octet-stream')
end
- context 'private project' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- end
+ it 'returns sha1 of the file' do
+ download_file(file_name: package_file.file_name + '.sha1')
- subject { download_file_with_token(file_name: package_file.file_name) }
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.media_type).to eq('text/plain')
+ expect(response.body).to eq(package_file.file_sha1)
+ end
- it_behaves_like 'tracking the file download event'
+ context 'with a non existing maven path' do
+ subject { download_file(file_name: package_file.file_name, path: 'foo/bar/1.2.3') }
- it 'returns the file' do
- subject
+ it_behaves_like 'rejecting the request for non existing maven path'
+ end
+ end
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('application/octet-stream')
- end
+ context 'private project' do
+ before do
+ project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
+ end
- it 'denies download when not enough permissions' do
- project.add_guest(user)
+ subject { download_file_with_token(file_name: package_file.file_name) }
- subject
+ it_behaves_like 'tracking the file download event'
- expect(response).to have_gitlab_http_status(:forbidden)
- end
+ it 'returns the file' do
+ subject
- it 'denies download when no private token' do
- download_file(file_name: package_file.file_name)
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.media_type).to eq('application/octet-stream')
+ end
- expect(response).to have_gitlab_http_status(:not_found)
- end
+ it 'denies download when not enough permissions' do
+ project.add_guest(user)
- it_behaves_like 'downloads with a job token'
+ subject
- it_behaves_like 'downloads with a deploy token'
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
- context 'with a non existing maven path' do
- subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3') }
+ it 'denies download when no private token' do
+ download_file(file_name: package_file.file_name)
- it_behaves_like 'rejecting the request for non existing maven path'
- end
+ expect(response).to have_gitlab_http_status(:not_found)
end
- end
- context 'with check_maven_path_first enabled' do
- before do
- stub_feature_flags(check_maven_path_first: true)
- end
+ it_behaves_like 'downloads with a job token'
- it_behaves_like 'handling all conditions'
- end
+ it_behaves_like 'downloads with a deploy token'
- context 'with check_maven_path_first disabled' do
- before do
- stub_feature_flags(check_maven_path_first: false)
- end
+ context 'with a non existing maven path' do
+ subject { download_file_with_token(file_name: package_file.file_name, path: 'foo/bar/1.2.3') }
- it_behaves_like 'handling all conditions'
+ it_behaves_like 'rejecting the request for non existing maven path'
+ end
end
def download_file(file_name:, params: {}, request_headers: headers, path: maven_metadatum.path)
@@ -1020,4 +1046,10 @@ RSpec.describe API::MavenPackages do
upload_file(params: params, request_headers: request_headers, file_extension: file_extension)
end
end
+
+ def move_project_to_namespace(namespace)
+ project.update!(namespace: namespace)
+ package.update!(name: project.full_path)
+ maven_metadatum.update!(path: "#{package.name}/#{package.version}")
+ end
end