summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb')
-rw-r--r--spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb490
1 files changed, 325 insertions, 165 deletions
diff --git a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
index d3ad7aa0595..be051dcbb7b 100644
--- a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
@@ -1,270 +1,430 @@
# frozen_string_literal: true
-RSpec.shared_examples 'handling get metadata requests' do
+RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
+ using RSpec::Parameterized::TableSyntax
+
let_it_be(:package_dependency_link1) { create(:packages_dependency_link, package: package, dependency_type: :dependencies) }
let_it_be(:package_dependency_link2) { create(:packages_dependency_link, package: package, dependency_type: :devDependencies) }
let_it_be(:package_dependency_link3) { create(:packages_dependency_link, package: package, dependency_type: :bundleDependencies) }
let_it_be(:package_dependency_link4) { create(:packages_dependency_link, package: package, dependency_type: :peerDependencies) }
- let(:params) { {} }
let(:headers) { {} }
- subject { get(url, params: params, headers: headers) }
+ subject { get(url, headers: headers) }
- shared_examples 'returning the npm package info' do
- it 'returns the package info' do
+ shared_examples 'accept metadata request' do |status:|
+ it 'accepts the metadata request' do
subject
- expect_a_valid_package_response
+ expect(response).to have_gitlab_http_status(status)
+ expect(response.media_type).to eq('application/json')
+ expect(response).to match_response_schema('public_api/v4/packages/npm_package')
+ expect(json_response['name']).to eq(package.name)
+ expect(json_response['versions'][package.version]).to match_schema('public_api/v4/packages/npm_package_version')
+ ::Packages::Npm::PackagePresenter::NPM_VALID_DEPENDENCY_TYPES.each do |dependency_type|
+ expect(json_response.dig('versions', package.version, dependency_type.to_s)).to be_any
+ end
+ expect(json_response['dist-tags']).to match_schema('public_api/v4/packages/npm_package_tags')
end
end
- shared_examples 'a package that requires auth' do
- it 'denies request without oauth token' do
+ shared_examples 'reject metadata request' do |status:|
+ it 'rejects the metadata request' do
subject
- expect(response).to have_gitlab_http_status(:not_found)
+ expect(response).to have_gitlab_http_status(status)
end
+ end
- context 'with oauth token' do
- let(:params) { { access_token: token.token } }
-
- it 'returns the package info with oauth token' do
- subject
+ shared_examples 'redirect metadata request' do |status:|
+ it 'redirects metadata request' do
+ subject
- expect_a_valid_package_response
- end
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response.headers['Location']).to eq("https://registry.npmjs.org/#{package_name}")
end
+ end
- context 'with job token' do
- let(:params) { { job_token: job.token } }
-
- it 'returns the package info with running job token' do
- subject
+ where(:auth, :package_name_type, :request_forward, :visibility, :user_role, :expected_result, :expected_status) do
+ nil | :scoped_naming_convention | true | 'PUBLIC' | nil | :accept | :ok
+ nil | :scoped_naming_convention | false | 'PUBLIC' | nil | :accept | :ok
+ nil | :non_existing | true | 'PUBLIC' | nil | :redirect | :redirected
+ nil | :non_existing | false | 'PUBLIC' | nil | :reject | :not_found
+ nil | :scoped_naming_convention | true | 'PRIVATE' | nil | :reject | :not_found
+ nil | :scoped_naming_convention | false | 'PRIVATE' | nil | :reject | :not_found
+ nil | :non_existing | true | 'PRIVATE' | nil | :redirect | :redirected
+ nil | :non_existing | false | 'PRIVATE' | nil | :reject | :not_found
+ nil | :scoped_naming_convention | true | 'INTERNAL' | nil | :reject | :not_found
+ nil | :scoped_naming_convention | false | 'INTERNAL' | nil | :reject | :not_found
+ nil | :non_existing | true | 'INTERNAL' | nil | :redirect | :redirected
+ nil | :non_existing | false | 'INTERNAL' | nil | :reject | :not_found
+
+ :oauth | :scoped_naming_convention | true | 'PUBLIC' | :guest | :accept | :ok
+ :oauth | :scoped_naming_convention | true | 'PUBLIC' | :reporter | :accept | :ok
+ :oauth | :scoped_naming_convention | false | 'PUBLIC' | :guest | :accept | :ok
+ :oauth | :scoped_naming_convention | false | 'PUBLIC' | :reporter | :accept | :ok
+ :oauth | :non_existing | true | 'PUBLIC' | :guest | :redirect | :redirected
+ :oauth | :non_existing | true | 'PUBLIC' | :reporter | :redirect | :redirected
+ :oauth | :non_existing | false | 'PUBLIC' | :guest | :reject | :not_found
+ :oauth | :non_existing | false | 'PUBLIC' | :reporter | :reject | :not_found
+ :oauth | :scoped_naming_convention | true | 'PRIVATE' | :guest | :reject | :forbidden
+ :oauth | :scoped_naming_convention | true | 'PRIVATE' | :reporter | :accept | :ok
+ :oauth | :scoped_naming_convention | false | 'PRIVATE' | :guest | :reject | :forbidden
+ :oauth | :scoped_naming_convention | false | 'PRIVATE' | :reporter | :accept | :ok
+ :oauth | :non_existing | true | 'PRIVATE' | :guest | :redirect | :redirected
+ :oauth | :non_existing | true | 'PRIVATE' | :reporter | :redirect | :redirected
+ :oauth | :non_existing | false | 'PRIVATE' | :guest | :reject | :forbidden
+ :oauth | :non_existing | false | 'PRIVATE' | :reporter | :reject | :not_found
+ :oauth | :scoped_naming_convention | true | 'INTERNAL' | :guest | :accept | :ok
+ :oauth | :scoped_naming_convention | true | 'INTERNAL' | :reporter | :accept | :ok
+ :oauth | :scoped_naming_convention | false | 'INTERNAL' | :guest | :accept | :ok
+ :oauth | :scoped_naming_convention | false | 'INTERNAL' | :reporter | :accept | :ok
+ :oauth | :non_existing | true | 'INTERNAL' | :guest | :redirect | :redirected
+ :oauth | :non_existing | true | 'INTERNAL' | :reporter | :redirect | :redirected
+ :oauth | :non_existing | false | 'INTERNAL' | :guest | :reject | :not_found
+ :oauth | :non_existing | false | 'INTERNAL' | :reporter | :reject | :not_found
+
+ :personal_access_token | :scoped_naming_convention | true | 'PUBLIC' | :guest | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | true | 'PUBLIC' | :reporter | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | false | 'PUBLIC' | :guest | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | false | 'PUBLIC' | :reporter | :accept | :ok
+ :personal_access_token | :non_existing | true | 'PUBLIC' | :guest | :redirect | :redirected
+ :personal_access_token | :non_existing | true | 'PUBLIC' | :reporter | :redirect | :redirected
+ :personal_access_token | :non_existing | false | 'PUBLIC' | :guest | :reject | :not_found
+ :personal_access_token | :non_existing | false | 'PUBLIC' | :reporter | :reject | :not_found
+ :personal_access_token | :scoped_naming_convention | true | 'PRIVATE' | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_naming_convention | true | 'PRIVATE' | :reporter | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | false | 'PRIVATE' | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_naming_convention | false | 'PRIVATE' | :reporter | :accept | :ok
+ :personal_access_token | :non_existing | true | 'PRIVATE' | :guest | :redirect | :redirected
+ :personal_access_token | :non_existing | true | 'PRIVATE' | :reporter | :redirect | :redirected
+ :personal_access_token | :non_existing | false | 'PRIVATE' | :guest | :reject | :forbidden
+ :personal_access_token | :non_existing | false | 'PRIVATE' | :reporter | :reject | :not_found
+ :personal_access_token | :scoped_naming_convention | true | 'INTERNAL' | :guest | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | true | 'INTERNAL' | :reporter | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | false | 'INTERNAL' | :guest | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | false | 'INTERNAL' | :reporter | :accept | :ok
+ :personal_access_token | :non_existing | true | 'INTERNAL' | :guest | :redirect | :redirected
+ :personal_access_token | :non_existing | true | 'INTERNAL' | :reporter | :redirect | :redirected
+ :personal_access_token | :non_existing | false | 'INTERNAL' | :guest | :reject | :not_found
+ :personal_access_token | :non_existing | false | 'INTERNAL' | :reporter | :reject | :not_found
+
+ :job_token | :scoped_naming_convention | true | 'PUBLIC' | :developer | :accept | :ok
+ :job_token | :scoped_naming_convention | false | 'PUBLIC' | :developer | :accept | :ok
+ :job_token | :non_existing | true | 'PUBLIC' | :developer | :redirect | :redirected
+ :job_token | :non_existing | false | 'PUBLIC' | :developer | :reject | :not_found
+ :job_token | :scoped_naming_convention | true | 'PRIVATE' | :developer | :accept | :ok
+ :job_token | :scoped_naming_convention | false | 'PRIVATE' | :developer | :accept | :ok
+ :job_token | :non_existing | true | 'PRIVATE' | :developer | :redirect | :redirected
+ :job_token | :non_existing | false | 'PRIVATE' | :developer | :reject | :not_found
+ :job_token | :scoped_naming_convention | true | 'INTERNAL' | :developer | :accept | :ok
+ :job_token | :scoped_naming_convention | false | 'INTERNAL' | :developer | :accept | :ok
+ :job_token | :non_existing | true | 'INTERNAL' | :developer | :redirect | :redirected
+ :job_token | :non_existing | false | 'INTERNAL' | :developer | :reject | :not_found
+
+ :deploy_token | :scoped_naming_convention | true | 'PUBLIC' | nil | :accept | :ok
+ :deploy_token | :scoped_naming_convention | false | 'PUBLIC' | nil | :accept | :ok
+ :deploy_token | :non_existing | true | 'PUBLIC' | nil | :redirect | :redirected
+ :deploy_token | :non_existing | false | 'PUBLIC' | nil | :reject | :not_found
+ :deploy_token | :scoped_naming_convention | true | 'PRIVATE' | nil | :accept | :ok
+ :deploy_token | :scoped_naming_convention | false | 'PRIVATE' | nil | :accept | :ok
+ :deploy_token | :non_existing | true | 'PRIVATE' | nil | :redirect | :redirected
+ :deploy_token | :non_existing | false | 'PRIVATE' | nil | :reject | :not_found
+ :deploy_token | :scoped_naming_convention | true | 'INTERNAL' | nil | :accept | :ok
+ :deploy_token | :scoped_naming_convention | false | 'INTERNAL' | nil | :accept | :ok
+ :deploy_token | :non_existing | true | 'INTERNAL' | nil | :redirect | :redirected
+ :deploy_token | :non_existing | false | 'INTERNAL' | nil | :reject | :not_found
+ end
- expect_a_valid_package_response
+ with_them do
+ include_context 'set package name from package name type'
+
+ let(:headers) do
+ case auth
+ when :oauth
+ build_token_auth_header(token.token)
+ when :personal_access_token
+ build_token_auth_header(personal_access_token.token)
+ when :job_token
+ build_token_auth_header(job.token)
+ when :deploy_token
+ build_token_auth_header(deploy_token.token)
+ else
+ {}
end
+ end
- it 'denies request without running job token' do
- job.update!(status: :success)
+ before do
+ project.send("add_#{user_role}", user) if user_role
+ project.update!(visibility: Gitlab::VisibilityLevel.const_get(visibility, false))
+ package.update!(name: package_name) unless package_name == 'non-existing-package'
+ stub_application_setting(npm_package_requests_forwarding: request_forward)
+ end
- subject
+ example_name = "#{params[:expected_result]} metadata request"
+ status = params[:expected_status]
- expect(response).to have_gitlab_http_status(:unauthorized)
+ if scope == :instance && params[:package_name_type] != :scoped_naming_convention
+ if params[:request_forward]
+ example_name = 'redirect metadata request'
+ status = :redirected
+ else
+ example_name = 'reject metadata request'
+ status = :not_found
end
end
- context 'with deploy token' do
- let(:headers) { build_token_auth_header(deploy_token.token) }
+ it_behaves_like example_name, status: status
+ end
- it 'returns the package info with deploy token' do
- subject
+ context 'with a developer' do
+ let(:headers) { build_token_auth_header(personal_access_token.token) }
- expect_a_valid_package_response
- end
+ before do
+ project.add_developer(user)
end
- end
-
- context 'a public project' do
- it_behaves_like 'returning the npm package info'
context 'project path with a dot' do
before do
project.update!(path: 'foo.bar')
end
- it_behaves_like 'returning the npm package info'
+ it_behaves_like 'accept metadata request', status: :ok
end
- context 'with request forward disabled' do
+ context 'with a job token' do
+ let(:headers) { build_token_auth_header(job.token) }
+
before do
- stub_application_setting(npm_package_requests_forwarding: false)
+ job.update!(status: :success)
end
- it_behaves_like 'returning the npm package info'
+ it_behaves_like 'reject metadata request', status: :unauthorized
+ end
+ end
+end
+
+RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
+ using RSpec::Parameterized::TableSyntax
+ include_context 'set package name from package name type'
- context 'with unknown package' do
- let(:package_name) { 'unknown' }
+ let_it_be(:package_tag1) { create(:packages_tag, package: package) }
+ let_it_be(:package_tag2) { create(:packages_tag, package: package) }
- it 'returns the proper response' do
- subject
+ let(:headers) { {} }
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
+ subject { get(url, headers: headers) }
+
+ shared_examples 'reject package tags request' do |status:|
+ before do
+ package.update!(name: package_name) unless package_name == 'non-existing-package'
end
- context 'with request forward enabled' do
- before do
- stub_application_setting(npm_package_requests_forwarding: true)
- end
+ it_behaves_like 'returning response status', status
+ end
- it_behaves_like 'returning the npm package info'
+ shared_examples 'handling different package names, visibilities and user roles' do
+ where(:package_name_type, :visibility, :user_role, :expected_result, :expected_status) do
+ :scoped_naming_convention | 'PUBLIC' | :anonymous | :accept | :ok
+ :scoped_naming_convention | 'PUBLIC' | :guest | :accept | :ok
+ :scoped_naming_convention | 'PUBLIC' | :reporter | :accept | :ok
+ :non_existing | 'PUBLIC' | :anonymous | :reject | :not_found
+ :non_existing | 'PUBLIC' | :guest | :reject | :not_found
+ :non_existing | 'PUBLIC' | :reporter | :reject | :not_found
+
+ :scoped_naming_convention | 'PRIVATE' | :anonymous | :reject | :not_found
+ :scoped_naming_convention | 'PRIVATE' | :guest | :reject | :forbidden
+ :scoped_naming_convention | 'PRIVATE' | :reporter | :accept | :ok
+ :non_existing | 'PRIVATE' | :anonymous | :reject | :not_found
+ :non_existing | 'PRIVATE' | :guest | :reject | :forbidden
+ :non_existing | 'PRIVATE' | :reporter | :reject | :not_found
+
+ :scoped_naming_convention | 'INTERNAL' | :anonymous | :reject | :not_found
+ :scoped_naming_convention | 'INTERNAL' | :guest | :accept | :ok
+ :scoped_naming_convention | 'INTERNAL' | :reporter | :accept | :ok
+ :non_existing | 'INTERNAL' | :anonymous | :reject | :not_found
+ :non_existing | 'INTERNAL' | :guest | :reject | :not_found
+ :non_existing | 'INTERNAL' | :reporter | :reject | :not_found
+ end
+
+ with_them do
+ let(:anonymous) { user_role == :anonymous }
- context 'with unknown package' do
- let(:package_name) { 'unknown' }
+ subject { get(url, headers: anonymous ? {} : headers) }
- it 'returns a redirect' do
- subject
+ before do
+ project.send("add_#{user_role}", user) unless anonymous
+ project.update!(visibility: Gitlab::VisibilityLevel.const_get(visibility, false))
+ end
- expect(response).to have_gitlab_http_status(:found)
- expect(response.headers['Location']).to eq('https://registry.npmjs.org/unknown')
- end
+ example_name = "#{params[:expected_result]} package tags request"
+ status = params[:expected_status]
- it_behaves_like 'a gitlab tracking event', described_class.name, 'npm_request_forward'
+ if scope == :instance && params[:package_name_type] != :scoped_naming_convention
+ example_name = 'reject package tags request'
+ status = :not_found
end
+
+ it_behaves_like example_name, status: status
end
end
- context 'internal project' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
- end
+ context 'with oauth token' do
+ let(:headers) { build_token_auth_header(token.token) }
- it_behaves_like 'a package that requires auth'
+ it_behaves_like 'handling different package names, visibilities and user roles'
end
- context 'private project' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- end
+ context 'with personal access token' do
+ let(:headers) { build_token_auth_header(personal_access_token.token) }
- it_behaves_like 'a package that requires auth'
+ it_behaves_like 'handling different package names, visibilities and user roles'
+ end
+end
- context 'with guest' do
- let(:params) { { access_token: token.token } }
+RSpec.shared_examples 'handling create dist tag requests' do |scope: :project|
+ using RSpec::Parameterized::TableSyntax
+ include_context 'set package name from package name type'
- it 'denies request when not enough permissions' do
- project.add_guest(user)
+ let_it_be(:tag_name) { 'test' }
- subject
+ let(:params) { {} }
+ let(:version) { package.version }
+ let(:env) { { 'api.request.body': version } }
+ let(:headers) { {} }
- expect(response).to have_gitlab_http_status(:forbidden)
- end
+ shared_examples 'reject create package tag request' do |status:|
+ before do
+ package.update!(name: package_name) unless package_name == 'non-existing-package'
end
+
+ it_behaves_like 'returning response status', status
end
- def expect_a_valid_package_response
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.media_type).to eq('application/json')
- expect(response).to match_response_schema('public_api/v4/packages/npm_package')
- expect(json_response['name']).to eq(package.name)
- expect(json_response['versions'][package.version]).to match_schema('public_api/v4/packages/npm_package_version')
- ::Packages::Npm::PackagePresenter::NPM_VALID_DEPENDENCY_TYPES.each do |dependency_type|
- expect(json_response.dig('versions', package.version, dependency_type.to_s)).to be_any
+ shared_examples 'handling different package names, visibilities and user roles' do
+ where(:package_name_type, :visibility, :user_role, :expected_result, :expected_status) do
+ :scoped_naming_convention | 'PUBLIC' | :anonymous | :reject | :forbidden
+ :scoped_naming_convention | 'PUBLIC' | :guest | :reject | :forbidden
+ :scoped_naming_convention | 'PUBLIC' | :developer | :accept | :ok
+ :non_existing | 'PUBLIC' | :anonymous | :reject | :forbidden
+ :non_existing | 'PUBLIC' | :guest | :reject | :forbidden
+ :non_existing | 'PUBLIC' | :developer | :reject | :not_found
+
+ :scoped_naming_convention | 'PRIVATE' | :anonymous | :reject | :not_found
+ :scoped_naming_convention | 'PRIVATE' | :guest | :reject | :forbidden
+ :scoped_naming_convention | 'PRIVATE' | :developer | :accept | :ok
+ :non_existing | 'PRIVATE' | :anonymous | :reject | :not_found
+ :non_existing | 'PRIVATE' | :guest | :reject | :forbidden
+ :non_existing | 'PRIVATE' | :developer | :reject | :not_found
+
+ :scoped_naming_convention | 'INTERNAL' | :anonymous | :reject | :forbidden
+ :scoped_naming_convention | 'INTERNAL' | :guest | :reject | :forbidden
+ :scoped_naming_convention | 'INTERNAL' | :developer | :accept | :ok
+ :non_existing | 'INTERNAL' | :anonymous | :reject | :forbidden
+ :non_existing | 'INTERNAL' | :guest | :reject | :forbidden
+ :non_existing | 'INTERNAL' | :developer | :reject | :not_found
end
- expect(json_response['dist-tags']).to match_schema('public_api/v4/packages/npm_package_tags')
- end
-end
-RSpec.shared_examples 'handling get dist tags requests' do
- let_it_be(:package_tag1) { create(:packages_tag, package: package) }
- let_it_be(:package_tag2) { create(:packages_tag, package: package) }
+ with_them do
+ let(:anonymous) { user_role == :anonymous }
- let(:params) { {} }
+ subject { put(url, env: env, headers: headers) }
- subject { get(url, params: params) }
+ before do
+ project.send("add_#{user_role}", user) unless anonymous
+ project.update!(visibility: Gitlab::VisibilityLevel.const_get(visibility, false))
+ end
- context 'with public project' do
- context 'with authenticated user' do
- let(:params) { { private_token: personal_access_token.token } }
+ example_name = "#{params[:expected_result]} create package tag request"
+ status = params[:expected_status]
- it_behaves_like 'returns package tags', :maintainer
- it_behaves_like 'returns package tags', :developer
- it_behaves_like 'returns package tags', :reporter
- it_behaves_like 'returns package tags', :guest
- end
+ if scope == :instance && params[:package_name_type] != :scoped_naming_convention
+ example_name = 'reject create package tag request'
+ status = :not_found
+ end
- context 'with unauthenticated user' do
- it_behaves_like 'returns package tags', :no_type
+ it_behaves_like example_name, status: status
end
end
- context 'with private project' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- end
+ context 'with oauth token' do
+ let(:headers) { build_token_auth_header(token.token) }
- context 'with authenticated user' do
- let(:params) { { private_token: personal_access_token.token } }
+ it_behaves_like 'handling different package names, visibilities and user roles'
+ end
- it_behaves_like 'returns package tags', :maintainer
- it_behaves_like 'returns package tags', :developer
- it_behaves_like 'returns package tags', :reporter
- it_behaves_like 'rejects package tags access', :guest, :forbidden
- end
+ context 'with personal access token' do
+ let(:headers) { build_token_auth_header(personal_access_token.token) }
- context 'with unauthenticated user' do
- it_behaves_like 'rejects package tags access', :no_type, :not_found
- end
+ it_behaves_like 'handling different package names, visibilities and user roles'
end
end
-RSpec.shared_examples 'handling create dist tag requests' do
- let_it_be(:tag_name) { 'test' }
+RSpec.shared_examples 'handling delete dist tag requests' do |scope: :project|
+ using RSpec::Parameterized::TableSyntax
+ include_context 'set package name from package name type'
- let(:params) { {} }
- let(:env) { {} }
- let(:version) { package.version }
-
- subject { put(url, env: env, params: params) }
+ let_it_be(:package_tag) { create(:packages_tag, package: package) }
- context 'with public project' do
- context 'with authenticated user' do
- let(:params) { { private_token: personal_access_token.token } }
- let(:env) { { 'api.request.body': version } }
+ let(:tag_name) { package_tag.name }
+ let(:headers) { {} }
- it_behaves_like 'create package tag', :maintainer
- it_behaves_like 'create package tag', :developer
- it_behaves_like 'rejects package tags access', :reporter, :forbidden
- it_behaves_like 'rejects package tags access', :guest, :forbidden
+ shared_examples 'reject delete package tag request' do |status:|
+ before do
+ package.update!(name: package_name) unless package_name == 'non-existing-package'
end
- context 'with unauthenticated user' do
- it_behaves_like 'rejects package tags access', :no_type, :unauthorized
- end
+ it_behaves_like 'returning response status', status
end
-end
-RSpec.shared_examples 'handling delete dist tag requests' do
- let_it_be(:package_tag) { create(:packages_tag, package: package) }
+ shared_examples 'handling different package names, visibilities and user roles' do
+ where(:package_name_type, :visibility, :user_role, :expected_result, :expected_status) do
+ :scoped_naming_convention | 'PUBLIC' | :anonymous | :reject | :forbidden
+ :scoped_naming_convention | 'PUBLIC' | :guest | :reject | :forbidden
+ :scoped_naming_convention | 'PUBLIC' | :maintainer | :accept | :ok
+ :non_existing | 'PUBLIC' | :anonymous | :reject | :forbidden
+ :non_existing | 'PUBLIC' | :guest | :reject | :forbidden
+ :non_existing | 'PUBLIC' | :maintainer | :reject | :not_found
+
+ :scoped_naming_convention | 'PRIVATE' | :anonymous | :reject | :not_found
+ :scoped_naming_convention | 'PRIVATE' | :guest | :reject | :forbidden
+ :scoped_naming_convention | 'PRIVATE' | :maintainer | :accept | :ok
+ :non_existing | 'INTERNAL' | :anonymous | :reject | :forbidden
+ :non_existing | 'INTERNAL' | :guest | :reject | :forbidden
+ :non_existing | 'INTERNAL' | :maintainer | :reject | :not_found
+ end
- let(:params) { {} }
- let(:tag_name) { package_tag.name }
+ with_them do
+ let(:anonymous) { user_role == :anonymous }
+
+ subject { delete(url, headers: headers) }
- subject { delete(url, params: params) }
+ before do
+ project.send("add_#{user_role}", user) unless anonymous
+ project.update!(visibility: Gitlab::VisibilityLevel.const_get(visibility, false))
+ end
- context 'with public project' do
- context 'with authenticated user' do
- let(:params) { { private_token: personal_access_token.token } }
+ example_name = "#{params[:expected_result]} delete package tag request"
+ status = params[:expected_status]
- it_behaves_like 'delete package tag', :maintainer
- it_behaves_like 'rejects package tags access', :developer, :forbidden
- it_behaves_like 'rejects package tags access', :reporter, :forbidden
- it_behaves_like 'rejects package tags access', :guest, :forbidden
- end
+ if scope == :instance && params[:package_name_type] != :scoped_naming_convention
+ example_name = 'reject delete package tag request'
+ status = :not_found
+ end
- context 'with unauthenticated user' do
- it_behaves_like 'rejects package tags access', :no_type, :unauthorized
+ it_behaves_like example_name, status: status
end
end
- context 'with private project' do
- before do
- project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- end
+ context 'with oauth token' do
+ let(:headers) { build_token_auth_header(token.token) }
- context 'with authenticated user' do
- let(:params) { { private_token: personal_access_token.token } }
+ it_behaves_like 'handling different package names, visibilities and user roles'
+ end
- it_behaves_like 'delete package tag', :maintainer
- it_behaves_like 'rejects package tags access', :developer, :forbidden
- it_behaves_like 'rejects package tags access', :reporter, :forbidden
- it_behaves_like 'rejects package tags access', :guest, :forbidden
- end
+ context 'with personal access token' do
+ let(:headers) { build_token_auth_header(personal_access_token.token) }
- context 'with unauthenticated user' do
- it_behaves_like 'rejects package tags access', :no_type, :unauthorized
- end
+ it_behaves_like 'handling different package names, visibilities and user roles'
end
end