summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/requests/api
diff options
context:
space:
mode:
Diffstat (limited to 'spec/support/shared_examples/requests/api')
-rw-r--r--spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb36
-rw-r--r--spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb38
-rw-r--r--spec/support/shared_examples/requests/api/discussions_shared_examples.rb15
-rw-r--r--spec/support/shared_examples/requests/api/graphql/issue_list_shared_examples.rb3
-rw-r--r--spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/graphql/mutations/subscription_shared_examples.rb6
-rw-r--r--spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/graphql/projects/branch_protections/access_level_request_examples.rb16
-rw-r--r--spec/support/shared_examples/requests/api/hooks_shared_examples.rb100
-rw-r--r--spec/support/shared_examples/requests/api/integrations/github_enterprise_jira_dvcs_end_of_life_shared_examples.rb23
-rw-r--r--spec/support/shared_examples/requests/api/integrations/slack/slack_request_verification_shared_examples.rb70
-rw-r--r--spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb9
-rw-r--r--spec/support/shared_examples/requests/api/labels_api_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/milestones_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/requests/api/ml/mlflow/mlflow_shared_examples.rb69
-rw-r--r--spec/support/shared_examples/requests/api/notes_shared_examples.rb88
-rw-r--r--spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb448
-rw-r--r--spec/support/shared_examples/requests/api/npm_packages_tags_shared_examples.rb29
-rw-r--r--spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb5
-rw-r--r--spec/support/shared_examples/requests/api/packages_shared_examples.rb46
-rw-r--r--spec/support/shared_examples/requests/api/pipelines/visibility_table_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb9
-rw-r--r--spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb20
-rw-r--r--spec/support/shared_examples/requests/api/resolvable_discussions_shared_examples.rb3
-rw-r--r--spec/support/shared_examples/requests/api/snippets_shared_examples.rb27
-rw-r--r--spec/support/shared_examples/requests/api/status_shared_examples.rb21
-rw-r--r--spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb3
29 files changed, 701 insertions, 409 deletions
diff --git a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
index f5c41416763..3ff52166990 100644
--- a/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/container_repositories_shared_examples.rb
@@ -18,7 +18,7 @@ RSpec.shared_examples 'returns repositories for allowed users' do |user_type, sc
subject
expect(json_response.length).to eq(2)
- expect(json_response.map { |repository| repository['id'] }).to contain_exactly(
+ expect(json_response.pluck('id')).to contain_exactly(
root_repository.id, test_repository.id)
expect(response.body).not_to include('tags')
expect(response.body).not_to include('tags_count')
@@ -47,7 +47,7 @@ RSpec.shared_examples 'returns tags for allowed users' do |user_type, scope|
subject
expect(json_response.length).to eq(2)
- expect(json_response.map { |repository| repository['id'] }).to contain_exactly(
+ expect(json_response.pluck('id')).to contain_exactly(
root_repository.id, test_repository.id)
expect(response.body).to include('tags')
end
diff --git a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
index f31cbcfdec1..804221b7416 100644
--- a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
@@ -4,7 +4,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
let!(:custom_attribute1) { attributable.custom_attributes.create! key: 'foo', value: 'foo' }
let!(:custom_attribute2) { attributable.custom_attributes.create! key: 'bar', value: 'bar' }
- describe "GET /#{attributable_name} with custom attributes filter" do
+ describe "GET /#{attributable_name} with custom attributes filter", :aggregate_failures do
before do
other_attributable
end
@@ -14,13 +14,13 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
get api("/#{attributable_name}", user), params: { custom_attributes: { foo: 'foo', bar: 'bar' } }
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.map { |r| r['id'] }).to include(attributable.id, other_attributable.id)
+ expect(json_response.pluck('id')).to include(attributable.id, other_attributable.id)
end
end
context 'with an authorized user' do
it 'filters by custom attributes' do
- get api("/#{attributable_name}", admin), params: { custom_attributes: { foo: 'foo', bar: 'bar' } }
+ get api("/#{attributable_name}", admin, admin_mode: true), params: { custom_attributes: { foo: 'foo', bar: 'bar' } }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.size).to be 1
@@ -29,7 +29,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
end
end
- describe "GET /#{attributable_name} with custom attributes" do
+ describe "GET /#{attributable_name} with custom attributes", :aggregate_failures do
before do
other_attributable
end
@@ -46,7 +46,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
context 'with an authorized user' do
it 'does not include custom attributes by default' do
- get api("/#{attributable_name}", admin)
+ get api("/#{attributable_name}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).not_to be_empty
@@ -54,7 +54,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
end
it 'includes custom attributes if requested' do
- get api("/#{attributable_name}", admin), params: { with_custom_attributes: true }
+ get api("/#{attributable_name}", admin, admin_mode: true), params: { with_custom_attributes: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).not_to be_empty
@@ -72,7 +72,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
end
end
- describe "GET /#{attributable_name}/:id with custom attributes" do
+ describe "GET /#{attributable_name}/:id with custom attributes", :aggregate_failures do
context 'with an unauthorized user' do
it 'does not include custom attributes' do
get api("/#{attributable_name}/#{attributable.id}", user), params: { with_custom_attributes: true }
@@ -84,14 +84,14 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
context 'with an authorized user' do
it 'does not include custom attributes by default' do
- get api("/#{attributable_name}/#{attributable.id}", admin)
+ get api("/#{attributable_name}/#{attributable.id}", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).not_to include 'custom_attributes'
end
it 'includes custom attributes if requested' do
- get api("/#{attributable_name}/#{attributable.id}", admin), params: { with_custom_attributes: true }
+ get api("/#{attributable_name}/#{attributable.id}", admin, admin_mode: true), params: { with_custom_attributes: true }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['custom_attributes']).to contain_exactly(
@@ -102,7 +102,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
end
end
- describe "GET /#{attributable_name}/:id/custom_attributes" do
+ describe "GET /#{attributable_name}/:id/custom_attributes", :aggregate_failures do
context 'with an unauthorized user' do
subject { get api("/#{attributable_name}/#{attributable.id}/custom_attributes", user) }
@@ -111,7 +111,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
context 'with an authorized user' do
it 'returns all custom attributes' do
- get api("/#{attributable_name}/#{attributable.id}/custom_attributes", admin)
+ get api("/#{attributable_name}/#{attributable.id}/custom_attributes", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to contain_exactly(
@@ -122,7 +122,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
end
end
- describe "GET /#{attributable_name}/:id/custom_attributes/:key" do
+ describe "GET /#{attributable_name}/:id/custom_attributes/:key", :aggregate_failures do
context 'with an unauthorized user' do
subject { get api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user) }
@@ -131,7 +131,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
context 'with an authorized user' do
it 'returns a single custom attribute' do
- get api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin)
+ get api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin, admin_mode: true)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq({ 'key' => 'foo', 'value' => 'foo' })
@@ -139,7 +139,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
end
end
- describe "PUT /#{attributable_name}/:id/custom_attributes/:key" do
+ describe "PUT /#{attributable_name}/:id/custom_attributes/:key", :aggregate_failures do
context 'with an unauthorized user' do
subject { put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user), params: { value: 'new' } }
@@ -149,7 +149,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
context 'with an authorized user' do
it 'creates a new custom attribute' do
expect do
- put api("/#{attributable_name}/#{attributable.id}/custom_attributes/new", admin), params: { value: 'new' }
+ put api("/#{attributable_name}/#{attributable.id}/custom_attributes/new", admin, admin_mode: true), params: { value: 'new' }
end.to change { attributable.custom_attributes.count }.by(1)
expect(response).to have_gitlab_http_status(:ok)
@@ -159,7 +159,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
it 'updates an existing custom attribute' do
expect do
- put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin), params: { value: 'new' }
+ put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin, admin_mode: true), params: { value: 'new' }
end.not_to change { attributable.custom_attributes.count }
expect(response).to have_gitlab_http_status(:ok)
@@ -169,7 +169,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
end
end
- describe "DELETE /#{attributable_name}/:id/custom_attributes/:key" do
+ describe "DELETE /#{attributable_name}/:id/custom_attributes/:key", :aggregate_failures do
context 'with an unauthorized user' do
subject { delete api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user) }
@@ -179,7 +179,7 @@ RSpec.shared_examples 'custom attributes endpoints' do |attributable_name|
context 'with an authorized user' do
it 'deletes an existing custom attribute' do
expect do
- delete api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin)
+ delete api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin, admin_mode: true)
end.to change { attributable.custom_attributes.count }.by(-1)
expect(response).to have_gitlab_http_status(:no_content)
diff --git a/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
index 6d29076da0f..bc7ad570441 100644
--- a/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
@@ -165,3 +165,41 @@ RSpec.shared_examples 'Debian packages write endpoint' do |desired_behavior, suc
it_behaves_like 'rejects Debian access with unknown container id', :unauthorized, :basic
end
+
+RSpec.shared_examples 'Debian packages endpoint catching ObjectStorage::RemoteStoreError' do
+ include_context 'Debian repository access', :public, :developer, :basic do
+ it "returns forbidden" do
+ expect(::Packages::Debian::CreatePackageFileService).to receive(:new).and_raise ObjectStorage::RemoteStoreError
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+end
+
+RSpec.shared_examples 'Debian packages index endpoint' do |success_body|
+ it_behaves_like 'Debian packages read endpoint', 'GET', :success, success_body
+
+ context 'when no ComponentFile is found' do
+ let(:target_component_name) { component.name + FFaker::Lorem.word }
+
+ it_behaves_like 'Debian packages read endpoint', 'GET', :no_content, /^$/
+ end
+end
+
+RSpec.shared_examples 'Debian packages index sha256 endpoint' do |success_body|
+ it_behaves_like 'Debian packages read endpoint', 'GET', :success, success_body
+
+ context 'with empty checksum' do
+ let(:target_sha256) { 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' }
+
+ it_behaves_like 'Debian packages read endpoint', 'GET', :no_content, /^$/
+ end
+
+ context 'when ComponentFile is not found' do
+ let(:target_component_name) { component.name + FFaker::Lorem.word }
+
+ it_behaves_like 'Debian packages read endpoint', 'GET', :not_found, /^{"message":"404 Not Found"}$/
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/discussions_shared_examples.rb b/spec/support/shared_examples/requests/api/discussions_shared_examples.rb
index f577e2ad323..2996c794e52 100644
--- a/spec/support/shared_examples/requests/api/discussions_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/discussions_shared_examples.rb
@@ -123,18 +123,6 @@ RSpec.shared_examples 'discussions API' do |parent_type, noteable_type, id_name,
expect_snowplow_event(category: 'Notes::CreateService', action: 'execute', label: 'note', value: anything)
end
- context 'with notes_create_service_tracking feature flag disabled' do
- before do
- stub_feature_flags(notes_create_service_tracking: false)
- end
-
- it 'does not track Notes::CreateService events', :snowplow do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions"), params: { body: 'hi!' }
-
- expect_no_snowplow_event(category: 'Notes::CreateService', action: 'execute')
- end
- end
-
context 'when an admin or owner makes the request' do
it 'accepts the creation date to be set' do
creation_time = 2.weeks.ago
@@ -243,8 +231,7 @@ RSpec.shared_examples 'discussions API' do |parent_type, noteable_type, id_name,
it 'returns a 404 error when note id not found' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}/notes/#{non_existing_record_id}", user),
- params: { body: 'Hello!' }
+ "discussions/#{note.discussion_id}/notes/#{non_existing_record_id}", user), params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/support/shared_examples/requests/api/graphql/issue_list_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/issue_list_shared_examples.rb
index 6c8b792bf92..930c47dac52 100644
--- a/spec/support/shared_examples/requests/api/graphql/issue_list_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/issue_list_shared_examples.rb
@@ -480,6 +480,7 @@ RSpec.shared_examples 'graphql issue list request spec' do
context 'when fetching escalation status' do
let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: issue_a) }
+ let_it_be(:incident_type) { WorkItems::Type.default_by_type(:incident) }
let(:fields) do
<<~QUERY
@@ -491,7 +492,7 @@ RSpec.shared_examples 'graphql issue list request spec' do
end
before do
- issue_a.update_columns(issue_type: Issue.issue_types[:incident])
+ issue_a.update_columns(issue_type: WorkItems::Type.base_types[:incident], work_item_type_id: incident_type.id)
end
it 'returns the escalation status values' do
diff --git a/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb
index b459e479c91..53329c5caec 100644
--- a/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/mutations/snippets_shared_examples.rb
@@ -6,7 +6,7 @@ RSpec.shared_examples 'when the snippet is not found' do
end
it_behaves_like 'a mutation that returns top-level errors',
- errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
+ errors: [Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR]
end
RSpec.shared_examples 'snippet edit usage data counters' do
diff --git a/spec/support/shared_examples/requests/api/graphql/mutations/subscription_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/mutations/subscription_shared_examples.rb
index 40b88ef370f..4dc0264172f 100644
--- a/spec/support/shared_examples/requests/api/graphql/mutations/subscription_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/mutations/subscription_shared_examples.rb
@@ -36,9 +36,9 @@ RSpec.shared_examples 'a subscribable resource api' do
context 'when the user is not authorized' do
it_behaves_like 'a mutation that returns top-level errors',
- errors: ["The resource that you are attempting to access "\
- "does not exist or you don't have permission to "\
- "perform this action"]
+ errors: ["The resource that you are attempting to access "\
+ "does not exist or you don't have permission to "\
+ "perform this action"]
end
context 'when user is authorized' do
diff --git a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
index f5835460a77..5e9dfc826d4 100644
--- a/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb
@@ -279,11 +279,11 @@ RSpec.shared_examples 'group and project packages query' do
end
def npm_pipeline_ids
- graphql_data_npm_package.dig('pipelines', 'nodes').map { |pipeline| pipeline['id'] }
+ graphql_data_npm_package.dig('pipelines', 'nodes').pluck('id')
end
def composer_pipeline_ids
- graphql_data_composer_package.dig('pipelines', 'nodes').map { |pipeline| pipeline['id'] }
+ graphql_data_composer_package.dig('pipelines', 'nodes').pluck('id')
end
def graphql_data_npm_package
diff --git a/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb b/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
index b4019d7c232..161f4a02b8c 100644
--- a/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb
@@ -38,7 +38,7 @@ RSpec.shared_examples 'a package with files' do
context 'with package files pending destruction' do
let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package) }
- let(:response_package_file_ids) { package_files_response.map { |pf| pf['id'] } }
+ let(:response_package_file_ids) { package_files_response.pluck('id') }
it 'does not return them' do
expect(package.reload.package_files).to include(package_file_pending_destruction)
diff --git a/spec/support/shared_examples/requests/api/graphql/projects/branch_protections/access_level_request_examples.rb b/spec/support/shared_examples/requests/api/graphql/projects/branch_protections/access_level_request_examples.rb
index 6b4d8cae2ce..6648c18fb70 100644
--- a/spec/support/shared_examples/requests/api/graphql/projects/branch_protections/access_level_request_examples.rb
+++ b/spec/support/shared_examples/requests/api/graphql/projects/branch_protections/access_level_request_examples.rb
@@ -13,13 +13,15 @@ RSpec.shared_examples 'a GraphQL query for access levels' do |access_level_kind|
let(:maintainer_access_level) { access_levels.for_role.first }
let(:maintainer_access_level_data) { access_levels_data.first }
let(:access_levels_data) do
- graphql_data_at('project',
- 'branchRules',
- 'nodes',
- 0,
- 'branchProtection',
- "#{access_level_kind.to_s.camelize(:lower)}AccessLevels",
- 'nodes')
+ graphql_data_at(
+ 'project',
+ 'branchRules',
+ 'nodes',
+ 0,
+ 'branchProtection',
+ "#{access_level_kind.to_s.camelize(:lower)}AccessLevels",
+ 'nodes'
+ )
end
let(:query) do
diff --git a/spec/support/shared_examples/requests/api/hooks_shared_examples.rb b/spec/support/shared_examples/requests/api/hooks_shared_examples.rb
index f2002de4b55..a2c34aa6a54 100644
--- a/spec/support/shared_examples/requests/api/hooks_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/hooks_shared_examples.rb
@@ -1,13 +1,13 @@
# frozen_string_literal: true
RSpec.shared_examples 'web-hook API endpoints test hook' do |prefix|
- describe "POST #{prefix}/:hook_id" do
+ describe "POST #{prefix}/:hook_id", :aggregate_failures do
it 'tests the hook' do
expect(WebHookService)
.to receive(:new).with(hook, anything, String, force: false)
.and_return(instance_double(WebHookService, execute: nil))
- post api(hook_uri, user)
+ post api(hook_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:created)
end
@@ -17,7 +17,7 @@ end
RSpec.shared_examples 'web-hook API endpoints with branch-filter' do |prefix|
describe "POST #{prefix}/hooks" do
it "returns a 422 error if branch filter is not valid" do
- post api(collection_uri, user),
+ post api(collection_uri, user, admin_mode: user.admin?),
params: { url: "http://example.com", push_events_branch_filter: '~badbranchname/' }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
@@ -58,10 +58,10 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
let(:default_values) { {} }
- describe "GET #{prefix}/hooks" do
+ describe "GET #{prefix}/hooks", :aggregate_failures do
context "authorized user" do
it "returns all hooks" do
- get api(collection_uri, user)
+ get api(collection_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_collection_schema
@@ -70,7 +70,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
context "when user is forbidden" do
it "prevents access to hooks" do
- get api(collection_uri, unauthorized_user)
+ get api(collection_uri, unauthorized_user, admin_mode: true)
expect(response).to have_gitlab_http_status(:forbidden)
end
@@ -90,7 +90,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
it 'returns the names of the url variables' do
- get api(collection_uri, user)
+ get api(collection_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to contain_exactly(
@@ -102,10 +102,10 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
end
- describe "GET #{prefix}/hooks/:hook_id" do
+ describe "GET #{prefix}/hooks/:hook_id", :aggregate_failures do
context "authorized user" do
it "returns a project hook" do
- get api(hook_uri, user)
+ get api(hook_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_hook_schema
@@ -114,7 +114,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
it "returns a 404 error if hook id is not available" do
- get api(hook_uri(non_existing_record_id), user)
+ get api(hook_uri(non_existing_record_id), user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -125,7 +125,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
it "has the correct alert status", :aggregate_failures do
- get api(hook_uri, user)
+ get api(hook_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
@@ -135,12 +135,12 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
context 'the hook is backed-off' do
before do
- WebHook::FAILURE_THRESHOLD.times { hook.backoff! }
+ WebHooks::AutoDisabling::FAILURE_THRESHOLD.times { hook.backoff! }
hook.backoff!
end
it "has the correct alert status", :aggregate_failures do
- get api(hook_uri, user)
+ get api(hook_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
@@ -156,7 +156,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
context "when user is forbidden" do
it "does not access an existing hook" do
- get api(hook_uri, unauthorized_user)
+ get api(hook_uri, unauthorized_user, admin_mode: true)
expect(response).to have_gitlab_http_status(:forbidden)
end
@@ -171,13 +171,12 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
end
- describe "POST #{prefix}/hooks" do
+ describe "POST #{prefix}/hooks", :aggregate_failures do
let(:hook_creation_params) { hook_params }
it "adds hook", :aggregate_failures do
expect do
- post api(collection_uri, user),
- params: hook_creation_params
+ post api(collection_uri, user, admin_mode: user.admin?), params: hook_creation_params
end.to change { hooks_count }.by(1)
expect(response).to have_gitlab_http_status(:created)
@@ -201,8 +200,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
token = "secret token"
expect do
- post api(collection_uri, user),
- params: { url: "http://example.com", token: token }
+ post api(collection_uri, user, admin_mode: user.admin?), params: { url: "http://example.com", token: token }
end.to change { hooks_count }.by(1)
expect(response).to have_gitlab_http_status(:created)
@@ -216,19 +214,19 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
it "returns a 400 error if url not given" do
- post api(collection_uri, user), params: { event_names.first => true }
+ post api(collection_uri, user, admin_mode: user.admin?), params: { event_names.first => true }
expect(response).to have_gitlab_http_status(:bad_request)
end
it "returns a 400 error if no parameters are provided" do
- post api(collection_uri, user)
+ post api(collection_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:bad_request)
end
it 'sets default values for events', :aggregate_failures do
- post api(collection_uri, user), params: { url: 'http://mep.mep' }
+ post api(collection_uri, user, admin_mode: user.admin?), params: { url: 'http://mep.mep' }
expect(response).to have_gitlab_http_status(:created)
expect(response).to match_hook_schema
@@ -239,22 +237,22 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
it "returns a 422 error if token not valid" do
- post api(collection_uri, user),
+ post api(collection_uri, user, admin_mode: user.admin?),
params: { url: "http://example.com", token: "foo\nbar" }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
it "returns a 422 error if url not valid" do
- post api(collection_uri, user), params: { url: "ftp://example.com" }
+ post api(collection_uri, user, admin_mode: user.admin?), params: { url: "ftp://example.com" }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
- describe "PUT #{prefix}/hooks/:hook_id" do
+ describe "PUT #{prefix}/hooks/:hook_id", :aggregate_failures do
it "updates an existing hook" do
- put api(hook_uri, user), params: update_params
+ put api(hook_uri, user, admin_mode: user.admin?), params: update_params
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_hook_schema
@@ -267,7 +265,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
it 'updates the URL variables' do
hook.update!(url_variables: { 'abc' => 'some value' })
- put api(hook_uri, user),
+ put api(hook_uri, user, admin_mode: user.admin?),
params: { url_variables: [{ key: 'def', value: 'other value' }] }
expect(response).to have_gitlab_http_status(:ok)
@@ -280,7 +278,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
it "adds the token without including it in the response" do
token = "secret token"
- put api(hook_uri, user), params: { url: "http://example.org", token: token }
+ put api(hook_uri, user, admin_mode: user.admin?), params: { url: "http://example.org", token: token }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response["url"]).to eq("http://example.org")
@@ -291,68 +289,68 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
end
it "returns 404 error if hook id not found" do
- put api(hook_uri(non_existing_record_id), user), params: { url: 'http://example.org' }
+ put api(hook_uri(non_existing_record_id), user, admin_mode: user.admin?), params: { url: 'http://example.org' }
expect(response).to have_gitlab_http_status(:not_found)
end
it "returns 400 error if no parameters are provided" do
- put api(hook_uri, user)
+ put api(hook_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:bad_request)
end
it "returns a 422 error if url is not valid" do
- put api(hook_uri, user), params: { url: 'ftp://example.com' }
+ put api(hook_uri, user, admin_mode: user.admin?), params: { url: 'ftp://example.com' }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
it "returns a 422 error if token is not valid" do
- put api(hook_uri, user), params: { token: %w[foo bar].join("\n") }
+ put api(hook_uri, user, admin_mode: user.admin?), params: { token: %w[foo bar].join("\n") }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
- describe "DELETE /projects/:id/hooks/:hook_id" do
+ describe "DELETE /projects/:id/hooks/:hook_id", :aggregate_failures do
it "deletes hook from project" do
expect do
- delete api(hook_uri, user)
+ delete api(hook_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:no_content)
end.to change { hooks_count }.by(-1)
end
it "returns a 404 error when deleting non existent hook" do
- delete api(hook_uri(non_existing_record_id), user)
+ delete api(hook_uri(non_existing_record_id), user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
it "returns a 404 error if hook id not given" do
- delete api(collection_uri, user)
+ delete api(collection_uri, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
it "returns forbidden if a user attempts to delete hooks they do not own" do
- delete api(hook_uri, unauthorized_user)
+ delete api(hook_uri, unauthorized_user, admin_mode: true)
expect(response).to have_gitlab_http_status(:forbidden)
expect(WebHook.exists?(hook.id)).to be_truthy
end
it_behaves_like '412 response' do
- let(:request) { api(hook_uri, user) }
+ let(:request) { api(hook_uri, user, admin_mode: user.admin?) }
end
end
describe "PUT #{prefix}/hooks/:hook_id/url_variables/:key", :aggregate_failures do
it 'sets the variable' do
expect do
- put api("#{hook_uri}/url_variables/abc", user),
- params: { value: 'some secret value' }
+ put api("#{hook_uri}/url_variables/abc", user, admin_mode: user.admin?),
+ params: { value: 'some secret value' }
end.to change { hook.reload.url_variables }.to(eq('abc' => 'some secret value'))
expect(response).to have_gitlab_http_status(:no_content)
@@ -361,30 +359,30 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
it 'overwrites existing values' do
hook.update!(url_variables: { 'abc' => 'xyz', 'def' => 'other value' })
- put api("#{hook_uri}/url_variables/abc", user),
- params: { value: 'some secret value' }
+ put api("#{hook_uri}/url_variables/abc", user, admin_mode: user.admin?),
+ params: { value: 'some secret value' }
expect(response).to have_gitlab_http_status(:no_content)
expect(hook.reload.url_variables).to eq('abc' => 'some secret value', 'def' => 'other value')
end
it "returns a 404 error when editing non existent hook" do
- put api("#{hook_uri(non_existing_record_id)}/url_variables/abc", user),
- params: { value: 'xyz' }
+ put api("#{hook_uri(non_existing_record_id)}/url_variables/abc", user, admin_mode: user.admin?),
+ params: { value: 'xyz' }
expect(response).to have_gitlab_http_status(:not_found)
end
it "returns a 422 error when the key is illegal" do
- put api("#{hook_uri}/url_variables/abc%20def", user),
- params: { value: 'xyz' }
+ put api("#{hook_uri}/url_variables/abc%20def", user, admin_mode: user.admin?),
+ params: { value: 'xyz' }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
it "returns a 422 error when the value is illegal" do
- put api("#{hook_uri}/url_variables/abc", user),
- params: { value: '' }
+ put api("#{hook_uri}/url_variables/abc", user, admin_mode: user.admin?),
+ params: { value: '' }
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
@@ -397,7 +395,7 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
it 'unsets the variable' do
expect do
- delete api("#{hook_uri}/url_variables/abc", user)
+ delete api("#{hook_uri}/url_variables/abc", user, admin_mode: user.admin?)
end.to change { hook.reload.url_variables }.to(eq({ 'def' => 'other value' }))
expect(response).to have_gitlab_http_status(:no_content)
@@ -406,13 +404,13 @@ RSpec.shared_examples 'web-hook API endpoints' do |prefix|
it 'returns 404 for keys that do not exist' do
hook.update!(url_variables: { 'def' => 'other value' })
- delete api("#{hook_uri}/url_variables/abc", user)
+ delete api("#{hook_uri}/url_variables/abc", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
it "returns a 404 error when deleting a variable from a non existent hook" do
- delete api(hook_uri(non_existing_record_id) + "/url_variables/abc", user)
+ delete api(hook_uri(non_existing_record_id) + "/url_variables/abc", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/support/shared_examples/requests/api/integrations/github_enterprise_jira_dvcs_end_of_life_shared_examples.rb b/spec/support/shared_examples/requests/api/integrations/github_enterprise_jira_dvcs_end_of_life_shared_examples.rb
new file mode 100644
index 00000000000..6799dec7b80
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/integrations/github_enterprise_jira_dvcs_end_of_life_shared_examples.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples 'a GitHub Enterprise Jira DVCS reversible end of life endpoint' do
+ it 'is a reachable endpoint' do
+ subject
+
+ expect(response).not_to have_gitlab_http_status(:not_found)
+ end
+
+ context 'when the flag is disabled' do
+ before do
+ stub_feature_flags(jira_dvcs_end_of_life_amnesty: false)
+ end
+
+ it 'presents as an endpoint that does not exist' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/integrations/slack/slack_request_verification_shared_examples.rb b/spec/support/shared_examples/requests/api/integrations/slack/slack_request_verification_shared_examples.rb
new file mode 100644
index 00000000000..ddda9ca6bcc
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/integrations/slack/slack_request_verification_shared_examples.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples 'Slack request verification' do
+ describe 'unauthorized request' do
+ shared_examples 'an unauthorized request' do
+ specify do
+ subject
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ shared_examples 'a successful request that generates a tracked error' do
+ specify do
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).once
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ expect(response.body).to be_empty
+ end
+ end
+
+ context 'when the slack_app_signing_secret setting is not set' do
+ before do
+ stub_application_setting(slack_app_signing_secret: nil)
+ end
+
+ it_behaves_like 'an unauthorized request'
+ end
+
+ context 'when the timestamp header has expired' do
+ before do
+ headers[::API::Integrations::Slack::Request::VERIFICATION_TIMESTAMP_HEADER] = 5.minutes.ago.to_i.to_s
+ end
+
+ it_behaves_like 'an unauthorized request'
+ end
+
+ context 'when the timestamp header is missing' do
+ before do
+ headers.delete(::API::Integrations::Slack::Request::VERIFICATION_TIMESTAMP_HEADER)
+ end
+
+ it_behaves_like 'an unauthorized request'
+ end
+
+ context 'when the signature header is missing' do
+ before do
+ headers.delete(::API::Integrations::Slack::Request::VERIFICATION_SIGNATURE_HEADER)
+ end
+
+ it_behaves_like 'an unauthorized request'
+ end
+
+ context 'when the signature is not verified' do
+ before do
+ headers[::API::Integrations::Slack::Request::VERIFICATION_SIGNATURE_HEADER] = 'unverified_signature'
+ end
+
+ it_behaves_like 'an unauthorized request'
+ end
+
+ context 'when type param is missing' do
+ it_behaves_like 'a successful request that generates a tracked error'
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb b/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
index 1045a92f332..e2c9874e7fc 100644
--- a/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/issuable_update_shared_examples.rb
@@ -34,5 +34,14 @@ RSpec.shared_examples 'issuable update endpoint' do
expect(json_response['labels']).to include '&'
expect(json_response['labels']).to include '?'
end
+
+ it 'clears milestone when milestone_id=0' do
+ entity.update!(milestone: milestone)
+
+ put api(url, user), params: { milestone_id: 0 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['milestone']).to be_nil
+ end
end
end
diff --git a/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb b/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb
index 41d21490343..fba0533251a 100644
--- a/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/labels_api_shared_examples.rb
@@ -9,6 +9,6 @@ RSpec.shared_examples 'fetches labels' do
expect(json_response).to be_an Array
expect(json_response).to all(match_schema('public_api/v4/labels/label'))
expect(json_response.size).to eq(expected_labels.size)
- expect(json_response.map { |r| r['name'] }).to match_array(expected_labels)
+ expect(json_response.pluck('name')).to match_array(expected_labels)
end
end
diff --git a/spec/support/shared_examples/requests/api/milestones_shared_examples.rb b/spec/support/shared_examples/requests/api/milestones_shared_examples.rb
index 1ea11ba3d7c..ee7d0e86771 100644
--- a/spec/support/shared_examples/requests/api/milestones_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/milestones_shared_examples.rb
@@ -52,7 +52,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
- expect(json_response.map { |m| m['id'] }).to match_array([closed_milestone.id, other_milestone.id])
+ expect(json_response.pluck('id')).to match_array([closed_milestone.id, other_milestone.id])
end
it 'does not return any milestone if none found' do
@@ -293,7 +293,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(json_response).to be_an Array
# 2 for projects, 3 for group(which has another project with an issue)
expect(json_response.size).to be_between(2, 3)
- expect(json_response.map { |issue| issue['id'] }).to include(issue.id, confidential_issue.id)
+ expect(json_response.pluck('id')).to include(issue.id, confidential_issue.id)
end
it 'does not return confidential issues to team members with guest role' do
@@ -306,7 +306,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
- expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
+ expect(json_response.pluck('id')).to include(issue.id)
end
it 'does not return confidential issues to regular users' do
@@ -316,7 +316,7 @@ RSpec.shared_examples 'group and project milestones' do |route_definition|
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.size).to eq(1)
- expect(json_response.map { |issue| issue['id'] }).to include(issue.id)
+ expect(json_response.pluck('id')).to include(issue.id)
end
it 'returns issues ordered by label priority' do
diff --git a/spec/support/shared_examples/requests/api/ml/mlflow/mlflow_shared_examples.rb b/spec/support/shared_examples/requests/api/ml/mlflow/mlflow_shared_examples.rb
new file mode 100644
index 00000000000..2ca62698daf
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/ml/mlflow/mlflow_shared_examples.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'MLflow|Not Found - Resource Does Not Exist' do
+ it "is Resource Does Not Exist", :aggregate_failures do
+ is_expected.to have_gitlab_http_status(:not_found)
+
+ expect(json_response).to include({ "error_code" => 'RESOURCE_DOES_NOT_EXIST' })
+ end
+end
+
+RSpec.shared_examples 'MLflow|Requires api scope' do
+ context 'when user has access but token has wrong scope' do
+ let(:access_token) { tokens[:read] }
+
+ it { is_expected.to have_gitlab_http_status(:forbidden) }
+ end
+end
+
+RSpec.shared_examples 'MLflow|Requires read_api scope' do
+ context 'when user has access but token has wrong scope' do
+ let(:access_token) { tokens[:no_access] }
+
+ it { is_expected.to have_gitlab_http_status(:forbidden) }
+ end
+end
+
+RSpec.shared_examples 'MLflow|Bad Request' do
+ it "is Bad Request" do
+ is_expected.to have_gitlab_http_status(:bad_request)
+ end
+end
+
+RSpec.shared_examples 'MLflow|shared error cases' do
+ context 'when not authenticated' do
+ let(:headers) { {} }
+
+ it "is Unauthorized" do
+ is_expected.to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'when user does not have access' do
+ let(:access_token) { tokens[:different_user] }
+
+ it "is Not Found" do
+ is_expected.to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when ff is disabled' do
+ let(:ff_value) { false }
+
+ it "is Not Found" do
+ is_expected.to have_gitlab_http_status(:not_found)
+ end
+ end
+end
+
+RSpec.shared_examples 'MLflow|Bad Request on missing required' do |keys|
+ keys.each do |key|
+ context "when \"#{key}\" is missing" do
+ let(:params) { default_params.tap { |p| p.delete(key) } }
+
+ it "is Bad Request" do
+ is_expected.to have_gitlab_http_status(:bad_request)
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/notes_shared_examples.rb b/spec/support/shared_examples/requests/api/notes_shared_examples.rb
index efe5ed3bcf9..b44ff952cdf 100644
--- a/spec/support/shared_examples/requests/api/notes_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/notes_shared_examples.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
- describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes" do
+ describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes", :aggregate_failures do
context 'sorting' do
before do
params = { noteable: noteable, author: user }
@@ -12,9 +12,9 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
context 'without sort params' do
it 'sorts by created_at in descending order by default' do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['created_at'] }
+ response_dates = json_response.pluck('created_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort.reverse)
@@ -23,7 +23,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'fetches notes using parent path as id paremeter' do
parent_id = CGI.escape(parent.full_path)
- get api("/#{parent_type}/#{parent_id}/#{noteable_type}/#{noteable[id_name]}/notes", user)
+ get api("/#{parent_type}/#{parent_id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
end
@@ -40,18 +40,18 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it 'page breaks first page correctly' do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?per_page=4", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?per_page=4", user, admin_mode: user.admin?)
- response_ids = json_response.map { |note| note['id'] }
+ response_ids = json_response.pluck('id')
expect(response_ids).to include(@note2.id)
expect(response_ids).not_to include(@first_note.id)
end
it 'page breaks second page correctly' do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?per_page=4&page=2", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?per_page=4&page=2", user, admin_mode: user.admin?)
- response_ids = json_response.map { |note| note['id'] }
+ response_ids = json_response.pluck('id')
expect(response_ids).not_to include(@note2.id)
expect(response_ids).to include(@first_note.id)
@@ -60,27 +60,27 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it 'sorts by ascending order when requested' do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?sort=asc", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?sort=asc", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['created_at'] }
+ response_dates = json_response.pluck('created_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort)
end
it 'sorts by updated_at in descending order when requested' do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['updated_at'] }
+ response_dates = json_response.pluck('updated_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort.reverse)
end
it 'sorts by updated_at in ascending order when requested' do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at&sort=asc", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes?order_by=updated_at&sort=asc", user, admin_mode: user.admin?)
- response_dates = json_response.map { |note| note['updated_at'] }
+ response_dates = json_response.pluck('updated_at')
expect(json_response.length).to eq(4)
expect(response_dates).to eq(response_dates.sort)
@@ -88,7 +88,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it "returns an array of notes" do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@@ -97,7 +97,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it "returns a 404 error when noteable id not found" do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{non_existing_record_id}/notes", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{non_existing_record_id}/notes", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -105,36 +105,36 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it "returns 404 when not authorized" do
parent.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE)
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user, admin_mode: private_user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
end
- describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do
+ describe "GET /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id", :aggregate_failures do
it "returns a note by id" do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['body']).to eq(note.note)
end
it "returns a 404 error if note not found" do
- get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{non_existing_record_id}", user)
+ get api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{non_existing_record_id}", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
end
- describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes" do
+ describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes", :aggregate_failures do
let(:params) { { body: 'hi!' } }
subject do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: params
end
it "creates a new note" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: 'hi!' }
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: { body: 'hi!' }
expect(response).to have_gitlab_http_status(:created)
expect(json_response['body']).to eq('hi!')
@@ -143,7 +143,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it "returns a 400 bad request error if body not given" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user)
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:bad_request)
end
@@ -158,7 +158,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
uri = "/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes"
expect do
- post api(uri, user), params: { body: 'hi!' }
+ post api(uri, user, admin_mode: user.admin?), params: { body: 'hi!' }
end.to change { Event.count }.by(1)
end
@@ -169,7 +169,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
context 'by an admin' do
it 'sets the creation time on the new note' do
admin = create(:admin)
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin), params: params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin, admin_mode: true), params: params
expect(response).to have_gitlab_http_status(:created)
expect(json_response['body']).to eq('hi!')
@@ -185,7 +185,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
let(:user) { project.first_owner }
it 'sets the creation time on the new note' do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: params
expect(response).to have_gitlab_http_status(:created)
expect(json_response['body']).to eq('hi!')
@@ -215,7 +215,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
when 'groups'
context 'by a group owner' do
it 'sets the creation time on the new note' do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: params
expect(response).to have_gitlab_http_status(:created)
expect(json_response['body']).to eq('hi!')
@@ -253,7 +253,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
context 'when the user is posting an award emoji on their own noteable' do
it 'creates a new note' do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: ':+1:' }
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: { body: ':+1:' }
expect(response).to have_gitlab_http_status(:created)
expect(json_response['body']).to eq(':+1:')
@@ -266,7 +266,7 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it 'responds with 404' do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user),
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user, admin_mode: private_user.admin?),
params: { body: 'Foo' }
expect(response).to have_gitlab_http_status(:not_found)
@@ -299,11 +299,11 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
end
- describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do
+ describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id", :aggregate_failures do
let(:params) { { body: 'Hello!' } }
subject do
- put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user), params: params
+ put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user, admin_mode: user.admin?), params: params
end
context 'when only body param is present' do
@@ -329,40 +329,40 @@ RSpec.shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it 'returns a 404 error when note id not found' do
- put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{non_existing_record_id}", user),
- params: { body: 'Hello!' }
+ put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{non_existing_record_id}", user, admin_mode: user.admin?),
+ params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns a 400 bad request error if body is empty' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "notes/#{note.id}", user), params: { body: '' }
+ "notes/#{note.id}", user, admin_mode: user.admin?), params: { body: '' }
expect(response).to have_gitlab_http_status(:bad_request)
end
end
- describe "DELETE /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do
+ describe "DELETE /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id", :aggregate_failures do
it 'deletes a note' do
delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "notes/#{note.id}", user)
+ "notes/#{note.id}", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:no_content)
# Check if note is really deleted
delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "notes/#{note.id}", user)
+ "notes/#{note.id}", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
it 'returns a 404 error when note id not found' do
- delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{non_existing_record_id}", user)
+ delete api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{non_existing_record_id}", user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
it_behaves_like '412 response' do
- let(:request) { api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user) }
+ let(:request) { api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/#{note.id}", user, admin_mode: user.admin?) }
end
end
end
@@ -370,16 +370,16 @@ end
RSpec.shared_examples 'noteable API with confidential notes' do |parent_type, noteable_type, id_name|
it_behaves_like 'noteable API', parent_type, noteable_type, id_name
- describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes" do
+ describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes", :aggregate_failures do
let(:params) { { body: 'hi!' } }
subject do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: params
end
context 'with internal param' do
it "creates a confidential note if internal is set to true" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params.merge(internal: true)
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: params.merge(internal: true)
expect(response).to have_gitlab_http_status(:created)
expect(json_response['body']).to eq('hi!')
@@ -391,7 +391,7 @@ RSpec.shared_examples 'noteable API with confidential notes' do |parent_type, no
context 'with deprecated confidential param' do
it "creates a confidential note if confidential is set to true" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params.merge(confidential: true)
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user, admin_mode: user.admin?), params: params.merge(confidential: true)
expect(response).to have_gitlab_http_status(:created)
expect(json_response['body']).to eq('hi!')
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 b55639a6b82..f53532d00d7 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
@@ -507,55 +507,118 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
it_behaves_like 'returning response status', status
end
- 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
- :scoped_no_naming_convention | :public | :anonymous | :accept | :ok
- :scoped_no_naming_convention | :public | :guest | :accept | :ok
- :scoped_no_naming_convention | :public | :reporter | :accept | :ok
- :unscoped | :public | :anonymous | :accept | :ok
- :unscoped | :public | :guest | :accept | :ok
- :unscoped | :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
- :scoped_no_naming_convention | :private | :anonymous | :reject | :not_found
- :scoped_no_naming_convention | :private | :guest | :reject | :forbidden
- :scoped_no_naming_convention | :private | :reporter | :accept | :ok
- :unscoped | :private | :anonymous | :reject | :not_found
- :unscoped | :private | :guest | :reject | :forbidden
- :unscoped | :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
- :scoped_no_naming_convention | :internal | :anonymous | :reject | :not_found
- :scoped_no_naming_convention | :internal | :guest | :accept | :ok
- :scoped_no_naming_convention | :internal | :reporter | :accept | :ok
- :unscoped | :internal | :anonymous | :reject | :not_found
- :unscoped | :internal | :guest | :accept | :ok
- :unscoped | :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
+ shared_examples 'handling all conditions' do
+ where(:auth, :package_name_type, :visibility, :user_role, :expected_result, :expected_status) do
+ nil | :scoped_naming_convention | :public | nil | :accept | :ok
+ nil | :scoped_no_naming_convention | :public | nil | :accept | :ok
+ nil | :unscoped | :public | nil | :accept | :ok
+ nil | :non_existing | :public | nil | :reject | :not_found
+ nil | :scoped_naming_convention | :private | nil | :reject | :not_found
+ nil | :scoped_no_naming_convention | :private | nil | :reject | :not_found
+ nil | :unscoped | :private | nil | :reject | :not_found
+ nil | :non_existing | :private | nil | :reject | :not_found
+ nil | :scoped_naming_convention | :internal | nil | :reject | :not_found
+ nil | :scoped_no_naming_convention | :internal | nil | :reject | :not_found
+ nil | :unscoped | :internal | nil | :reject | :not_found
+ nil | :non_existing | :internal | nil | :reject | :not_found
+
+ :oauth | :scoped_naming_convention | :public | :guest | :accept | :ok
+ :oauth | :scoped_naming_convention | :public | :reporter | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :public | :guest | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :public | :reporter | :accept | :ok
+ :oauth | :unscoped | :public | :guest | :accept | :ok
+ :oauth | :unscoped | :public | :reporter | :accept | :ok
+ :oauth | :non_existing | :public | :guest | :reject | :not_found
+ :oauth | :non_existing | :public | :reporter | :reject | :not_found
+ :oauth | :scoped_naming_convention | :private | :guest | :reject | :forbidden
+ :oauth | :scoped_naming_convention | :private | :reporter | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :private | :guest | :reject | :forbidden
+ :oauth | :scoped_no_naming_convention | :private | :reporter | :accept | :ok
+ :oauth | :unscoped | :private | :guest | :reject | :forbidden
+ :oauth | :unscoped | :private | :reporter | :accept | :ok
+ :oauth | :non_existing | :private | :guest | :reject | :forbidden
+ :oauth | :non_existing | :private | :reporter | :reject | :not_found
+ :oauth | :scoped_naming_convention | :internal | :guest | :accept | :ok
+ :oauth | :scoped_naming_convention | :internal | :reporter | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :internal | :guest | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :internal | :reporter | :accept | :ok
+ :oauth | :unscoped | :internal | :guest | :accept | :ok
+ :oauth | :unscoped | :internal | :reporter | :accept | :ok
+ :oauth | :non_existing | :internal | :guest | :reject | :not_found
+ :oauth | :non_existing | :internal | :reporter | :reject | :not_found
+
+ :personal_access_token | :scoped_naming_convention | :public | :guest | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | :public | :reporter | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :public | :guest | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :public | :reporter | :accept | :ok
+ :personal_access_token | :unscoped | :public | :guest | :accept | :ok
+ :personal_access_token | :unscoped | :public | :reporter | :accept | :ok
+ :personal_access_token | :non_existing | :public | :guest | :reject | :not_found
+ :personal_access_token | :non_existing | :public | :reporter | :reject | :not_found
+ :personal_access_token | :scoped_naming_convention | :private | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_naming_convention | :private | :reporter | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :private | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_no_naming_convention | :private | :reporter | :accept | :ok
+ :personal_access_token | :unscoped | :private | :guest | :reject | :forbidden
+ :personal_access_token | :unscoped | :private | :reporter | :accept | :ok
+ :personal_access_token | :non_existing | :private | :guest | :reject | :forbidden
+ :personal_access_token | :non_existing | :private | :reporter | :reject | :not_found
+ :personal_access_token | :scoped_naming_convention | :internal | :guest | :accept | :ok
+ :personal_access_token | :scoped_naming_convention | :internal | :reporter | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :internal | :guest | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :internal | :reporter | :accept | :ok
+ :personal_access_token | :unscoped | :internal | :guest | :accept | :ok
+ :personal_access_token | :unscoped | :internal | :reporter | :accept | :ok
+ :personal_access_token | :non_existing | :internal | :guest | :reject | :not_found
+ :personal_access_token | :non_existing | :internal | :reporter | :reject | :not_found
+
+ :job_token | :scoped_naming_convention | :public | :developer | :accept | :ok
+ :job_token | :scoped_no_naming_convention | :public | :developer | :accept | :ok
+ :job_token | :unscoped | :public | :developer | :accept | :ok
+ :job_token | :non_existing | :public | :developer | :reject | :not_found
+ :job_token | :scoped_naming_convention | :private | :developer | :accept | :ok
+ :job_token | :scoped_no_naming_convention | :private | :developer | :accept | :ok
+ :job_token | :unscoped | :private | :developer | :accept | :ok
+ :job_token | :non_existing | :private | :developer | :reject | :not_found
+ :job_token | :scoped_naming_convention | :internal | :developer | :accept | :ok
+ :job_token | :scoped_no_naming_convention | :internal | :developer | :accept | :ok
+ :job_token | :unscoped | :internal | :developer | :accept | :ok
+ :job_token | :non_existing | :internal | :developer | :reject | :not_found
+
+ :deploy_token | :scoped_naming_convention | :public | nil | :accept | :ok
+ :deploy_token | :scoped_no_naming_convention | :public | nil | :accept | :ok
+ :deploy_token | :unscoped | :public | nil | :accept | :ok
+ :deploy_token | :non_existing | :public | nil | :reject | :not_found
+ :deploy_token | :scoped_naming_convention | :private | nil | :accept | :ok
+ :deploy_token | :scoped_no_naming_convention | :private | nil | :accept | :ok
+ :deploy_token | :unscoped | :private | nil | :accept | :ok
+ :deploy_token | :non_existing | :private | nil | :reject | :not_found
+ :deploy_token | :scoped_naming_convention | :internal | nil | :accept | :ok
+ :deploy_token | :scoped_no_naming_convention | :internal | nil | :accept | :ok
+ :deploy_token | :unscoped | :internal | nil | :accept | :ok
+ :deploy_token | :non_existing | :internal | nil | :reject | :not_found
end
with_them do
- let(:anonymous) { user_role == :anonymous }
+ let(:headers) do
+ case auth
+ when :oauth
+ build_token_auth_header(token.plaintext_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
- subject { get(url, headers: anonymous ? {} : headers) }
+ subject { get(url, headers: headers) }
before do
- project.send("add_#{user_role}", user) unless anonymous
+ project.send("add_#{user_role}", user) if user_role
project.update!(visibility: visibility.to_s)
end
@@ -571,20 +634,6 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
end
end
- shared_examples 'handling all conditions' do
- context 'with oauth token' do
- let(:headers) { build_token_auth_header(token.plaintext_token) }
-
- it_behaves_like 'handling different package names, visibilities and user roles'
- end
-
- context 'with personal access token' do
- let(:headers) { build_token_auth_header(personal_access_token.token) }
-
- it_behaves_like 'handling different package names, visibilities and user roles'
- end
- end
-
context 'with a group namespace' do
it_behaves_like 'handling all conditions'
end
@@ -599,7 +648,6 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
end
RSpec.shared_examples 'handling create dist tag requests' do |scope: :project|
- using RSpec::Parameterized::TableSyntax
include_context 'set package name from package name type'
let_it_be(:tag_name) { 'test' }
@@ -617,82 +665,10 @@ RSpec.shared_examples 'handling create dist tag requests' do |scope: :project|
it_behaves_like 'returning response status', status
end
- 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
- :scoped_no_naming_convention | :public | :anonymous | :reject | :forbidden
- :scoped_no_naming_convention | :public | :guest | :reject | :forbidden
- :scoped_no_naming_convention | :public | :developer | :accept | :ok
- :unscoped | :public | :anonymous | :reject | :forbidden
- :unscoped | :public | :guest | :reject | :forbidden
- :unscoped | :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
- :scoped_no_naming_convention | :private | :anonymous | :reject | :not_found
- :scoped_no_naming_convention | :private | :guest | :reject | :forbidden
- :scoped_no_naming_convention | :private | :developer | :accept | :ok
- :unscoped | :private | :anonymous | :reject | :not_found
- :unscoped | :private | :guest | :reject | :forbidden
- :unscoped | :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
- :scoped_no_naming_convention | :internal | :anonymous | :reject | :forbidden
- :scoped_no_naming_convention | :internal | :guest | :reject | :forbidden
- :scoped_no_naming_convention | :internal | :developer | :accept | :ok
- :unscoped | :internal | :anonymous | :reject | :forbidden
- :unscoped | :internal | :guest | :reject | :forbidden
- :unscoped | :internal | :developer | :accept | :ok
- :non_existing | :internal | :anonymous | :reject | :forbidden
- :non_existing | :internal | :guest | :reject | :forbidden
- :non_existing | :internal | :developer | :reject | :not_found
- end
-
- with_them do
- let(:anonymous) { user_role == :anonymous }
-
- subject { put(url, env: env, headers: headers) }
-
- before do
- project.send("add_#{user_role}", user) unless anonymous
- project.update!(visibility: visibility.to_s)
- end
-
- example_name = "#{params[:expected_result]} create package tag request"
- status = params[:expected_status]
-
- if scope == :instance && params[:package_name_type] != :scoped_naming_convention
- example_name = 'reject create package tag request'
- status = :not_found
- end
-
- it_behaves_like example_name, status: status
- end
- end
-
shared_examples 'handling all conditions' do
- context 'with oauth token' do
- let(:headers) { build_token_auth_header(token.plaintext_token) }
+ subject { put(url, env: env, headers: headers) }
- it_behaves_like 'handling different package names, visibilities and user roles'
- end
-
- context 'with personal access token' do
- let(:headers) { build_token_auth_header(personal_access_token.token) }
-
- it_behaves_like 'handling different package names, visibilities and user roles'
- end
+ it_behaves_like 'handling different package names, visibilities and user roles for tags create or delete', action: :create, scope: scope
end
context 'with a group namespace' do
@@ -709,7 +685,6 @@ RSpec.shared_examples 'handling create dist tag requests' do |scope: :project|
end
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_it_be(:package_tag) { create(:packages_tag, package: package) }
@@ -725,82 +700,10 @@ RSpec.shared_examples 'handling delete dist tag requests' do |scope: :project|
it_behaves_like 'returning response status', status
end
- 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
- :scoped_no_naming_convention | :public | :anonymous | :reject | :forbidden
- :scoped_no_naming_convention | :public | :guest | :reject | :forbidden
- :scoped_no_naming_convention | :public | :maintainer | :accept | :ok
- :unscoped | :public | :anonymous | :reject | :forbidden
- :unscoped | :public | :guest | :reject | :forbidden
- :unscoped | :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
- :scoped_no_naming_convention | :private | :anonymous | :reject | :not_found
- :scoped_no_naming_convention | :private | :guest | :reject | :forbidden
- :scoped_no_naming_convention | :private | :maintainer | :accept | :ok
- :unscoped | :private | :anonymous | :reject | :not_found
- :unscoped | :private | :guest | :reject | :forbidden
- :unscoped | :private | :maintainer | :accept | :ok
- :non_existing | :private | :anonymous | :reject | :not_found
- :non_existing | :private | :guest | :reject | :forbidden
- :non_existing | :private | :maintainer | :reject | :not_found
-
- :scoped_naming_convention | :internal | :anonymous | :reject | :forbidden
- :scoped_naming_convention | :internal | :guest | :reject | :forbidden
- :scoped_naming_convention | :internal | :maintainer | :accept | :ok
- :scoped_no_naming_convention | :internal | :anonymous | :reject | :forbidden
- :scoped_no_naming_convention | :internal | :guest | :reject | :forbidden
- :scoped_no_naming_convention | :internal | :maintainer | :accept | :ok
- :unscoped | :internal | :anonymous | :reject | :forbidden
- :unscoped | :internal | :guest | :reject | :forbidden
- :unscoped | :internal | :maintainer | :accept | :ok
- :non_existing | :internal | :anonymous | :reject | :forbidden
- :non_existing | :internal | :guest | :reject | :forbidden
- :non_existing | :internal | :maintainer | :reject | :not_found
- end
-
- with_them do
- let(:anonymous) { user_role == :anonymous }
-
- subject { delete(url, headers: headers) }
-
- before do
- project.send("add_#{user_role}", user) unless anonymous
- project.update!(visibility: visibility.to_s)
- end
-
- example_name = "#{params[:expected_result]} delete package tag request"
- status = params[:expected_status]
-
- if scope == :instance && params[:package_name_type] != :scoped_naming_convention
- example_name = 'reject delete package tag request'
- status = :not_found
- end
-
- it_behaves_like example_name, status: status
- end
- end
-
shared_examples 'handling all conditions' do
- context 'with oauth token' do
- let(:headers) { build_token_auth_header(token.plaintext_token) }
-
- it_behaves_like 'handling different package names, visibilities and user roles'
- end
-
- context 'with personal access token' do
- let(:headers) { build_token_auth_header(personal_access_token.token) }
+ subject { delete(url, headers: headers) }
- it_behaves_like 'handling different package names, visibilities and user roles'
- end
+ it_behaves_like 'handling different package names, visibilities and user roles for tags create or delete', action: :delete, scope: scope
end
context 'with a group namespace' do
@@ -815,3 +718,134 @@ RSpec.shared_examples 'handling delete dist tag requests' do |scope: :project|
end
end
end
+
+RSpec.shared_examples 'handling different package names, visibilities and user roles for tags create or delete' do |action:, scope: :project|
+ using RSpec::Parameterized::TableSyntax
+
+ role = action == :create ? :developer : :maintainer
+
+ where(:auth, :package_name_type, :visibility, :user_role, :expected_result, :expected_status) do
+ nil | :scoped_naming_convention | :public | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | :public | nil | :reject | :unauthorized
+ nil | :unscoped | :public | nil | :reject | :unauthorized
+ nil | :non_existing | :public | nil | :reject | :unauthorized
+ nil | :scoped_naming_convention | :private | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | :private | nil | :reject | :unauthorized
+ nil | :unscoped | :private | nil | :reject | :unauthorized
+ nil | :non_existing | :private | nil | :reject | :unauthorized
+ nil | :scoped_naming_convention | :internal | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | :internal | nil | :reject | :unauthorized
+ nil | :unscoped | :internal | nil | :reject | :unauthorized
+ nil | :non_existing | :internal | nil | :reject | :unauthorized
+
+ :oauth | :scoped_naming_convention | :public | :guest | :reject | :forbidden
+ :oauth | :scoped_naming_convention | :public | role | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :public | :guest | :reject | :forbidden
+ :oauth | :scoped_no_naming_convention | :public | role | :accept | :ok
+ :oauth | :unscoped | :public | :guest | :reject | :forbidden
+ :oauth | :unscoped | :public | role | :accept | :ok
+ :oauth | :non_existing | :public | :guest | :reject | :forbidden
+ :oauth | :non_existing | :public | role | :reject | :not_found
+ :oauth | :scoped_naming_convention | :private | :guest | :reject | :forbidden
+ :oauth | :scoped_naming_convention | :private | role | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :private | :guest | :reject | :forbidden
+ :oauth | :scoped_no_naming_convention | :private | role | :accept | :ok
+ :oauth | :unscoped | :private | :guest | :reject | :forbidden
+ :oauth | :unscoped | :private | role | :accept | :ok
+ :oauth | :non_existing | :private | :guest | :reject | :forbidden
+ :oauth | :non_existing | :private | role | :reject | :not_found
+ :oauth | :scoped_naming_convention | :internal | :guest | :reject | :forbidden
+ :oauth | :scoped_naming_convention | :internal | role | :accept | :ok
+ :oauth | :scoped_no_naming_convention | :internal | :guest | :reject | :forbidden
+ :oauth | :scoped_no_naming_convention | :internal | role | :accept | :ok
+ :oauth | :unscoped | :internal | :guest | :reject | :forbidden
+ :oauth | :unscoped | :internal | role | :accept | :ok
+ :oauth | :non_existing | :internal | :guest | :reject | :forbidden
+ :oauth | :non_existing | :internal | role | :reject | :not_found
+
+ :personal_access_token | :scoped_naming_convention | :public | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_naming_convention | :public | role | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :public | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_no_naming_convention | :public | role | :accept | :ok
+ :personal_access_token | :unscoped | :public | :guest | :reject | :forbidden
+ :personal_access_token | :unscoped | :public | role | :accept | :ok
+ :personal_access_token | :non_existing | :public | :guest | :reject | :forbidden
+ :personal_access_token | :non_existing | :public | role | :reject | :not_found
+ :personal_access_token | :scoped_naming_convention | :private | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_naming_convention | :private | role | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :private | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_no_naming_convention | :private | role | :accept | :ok
+ :personal_access_token | :unscoped | :private | :guest | :reject | :forbidden
+ :personal_access_token | :unscoped | :private | role | :accept | :ok
+ :personal_access_token | :non_existing | :private | :guest | :reject | :forbidden
+ :personal_access_token | :non_existing | :private | role | :reject | :not_found
+ :personal_access_token | :scoped_naming_convention | :internal | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_naming_convention | :internal | role | :accept | :ok
+ :personal_access_token | :scoped_no_naming_convention | :internal | :guest | :reject | :forbidden
+ :personal_access_token | :scoped_no_naming_convention | :internal | role | :accept | :ok
+ :personal_access_token | :unscoped | :internal | :guest | :reject | :forbidden
+ :personal_access_token | :unscoped | :internal | role | :accept | :ok
+ :personal_access_token | :non_existing | :internal | :guest | :reject | :forbidden
+ :personal_access_token | :non_existing | :internal | role | :reject | :not_found
+
+ :job_token | :scoped_naming_convention | :public | role | :accept | :ok
+ :job_token | :scoped_no_naming_convention | :public | role | :accept | :ok
+ :job_token | :unscoped | :public | role | :accept | :ok
+ :job_token | :non_existing | :public | role | :reject | :not_found
+ :job_token | :scoped_naming_convention | :private | role | :accept | :ok
+ :job_token | :scoped_no_naming_convention | :private | role | :accept | :ok
+ :job_token | :unscoped | :private | role | :accept | :ok
+ :job_token | :non_existing | :private | role | :reject | :not_found
+ :job_token | :scoped_naming_convention | :internal | role | :accept | :ok
+ :job_token | :scoped_no_naming_convention | :internal | role | :accept | :ok
+ :job_token | :unscoped | :internal | role | :accept | :ok
+ :job_token | :non_existing | :internal | role | :reject | :not_found
+
+ :deploy_token | :scoped_naming_convention | :public | nil | :accept | :ok
+ :deploy_token | :scoped_no_naming_convention | :public | nil | :accept | :ok
+ :deploy_token | :unscoped | :public | nil | :accept | :ok
+ :deploy_token | :non_existing | :public | nil | :reject | :not_found
+ :deploy_token | :scoped_naming_convention | :private | nil | :accept | :ok
+ :deploy_token | :scoped_no_naming_convention | :private | nil | :accept | :ok
+ :deploy_token | :unscoped | :private | nil | :accept | :ok
+ :deploy_token | :non_existing | :private | nil | :reject | :not_found
+ :deploy_token | :scoped_naming_convention | :internal | nil | :accept | :ok
+ :deploy_token | :scoped_no_naming_convention | :internal | nil | :accept | :ok
+ :deploy_token | :unscoped | :internal | nil | :accept | :ok
+ :deploy_token | :non_existing | :internal | nil | :reject | :not_found
+ end
+
+ with_them do
+ let(:headers) do
+ case auth
+ when :oauth
+ build_token_auth_header(token.plaintext_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
+
+ before do
+ project.send("add_#{user_role}", user) if user_role
+ project.update!(visibility: visibility.to_s)
+ end
+
+ example_name = "#{params[:expected_result]} #{action} package tag request"
+ status = params[:expected_status]
+
+ if scope == :instance && params[:package_name_type] != :scoped_naming_convention
+ example_name = "reject #{action} package tag request"
+ # Due to #authenticate_non_get, anonymous requests on private resources
+ # are rejected with unauthorized status
+ status = params[:auth].nil? ? :unauthorized : :not_found
+ end
+
+ it_behaves_like example_name, status: status
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/npm_packages_tags_shared_examples.rb b/spec/support/shared_examples/requests/api/npm_packages_tags_shared_examples.rb
index 1d79a61fbb0..7c20ea661b5 100644
--- a/spec/support/shared_examples/requests/api/npm_packages_tags_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/npm_packages_tags_shared_examples.rb
@@ -1,13 +1,5 @@
# frozen_string_literal: true
-RSpec.shared_examples 'rejects package tags access' do |status:|
- before do
- package.update!(name: package_name) unless package_name == 'non-existing-package'
- end
-
- it_behaves_like 'returning response status', status
-end
-
RSpec.shared_examples 'accept package tags request' do |status:|
using RSpec::Parameterized::TableSyntax
include_context 'dependency proxy helpers context'
@@ -23,6 +15,7 @@ RSpec.shared_examples 'accept package tags request' do |status:|
end
it_behaves_like 'returning response status', status
+ it_behaves_like 'track event', :list_tags
it 'returns a valid json response' do
subject
@@ -63,6 +56,7 @@ RSpec.shared_examples 'accept create package tag request' do |user_type|
end
it_behaves_like 'returning response status', :no_content
+ it_behaves_like 'track event', :create_tag
it 'creates the package tag' do
expect { subject }.to change { Packages::Tag.count }.by(1)
@@ -145,6 +139,7 @@ RSpec.shared_examples 'accept delete package tag request' do |user_type|
end
it_behaves_like 'returning response status', :no_content
+ it_behaves_like 'track event', :delete_tag
it 'returns a valid response' do
subject
@@ -190,3 +185,21 @@ RSpec.shared_examples 'accept delete package tag request' do |user_type|
end
end
end
+
+RSpec.shared_examples 'track event' do |event_name|
+ let(:event_user) do
+ if auth == :deploy_token
+ deploy_token
+ elsif user_role
+ user
+ end
+ end
+
+ let(:snowplow_gitlab_standard_context) do
+ { project: project, namespace: project.namespace, property: 'i_package_npm_user' }.tap do |context|
+ context[:user] = event_user if event_user
+ end
+ end
+
+ it_behaves_like 'a package tracking event', described_class.name, event_name.to_s
+end
diff --git a/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb b/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb
index 17d8b9c7fab..7cafe8bb368 100644
--- a/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb
@@ -36,6 +36,7 @@ RSpec.shared_examples 'handling nuget service requests' do |example_names_with_s
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
+ let(:snowplow_gitlab_standard_context) { snowplow_context(user_role: user_role) }
subject { get api(url), headers: headers }
@@ -72,6 +73,7 @@ RSpec.shared_examples 'handling nuget service requests' do |example_names_with_s
with_them do
let(:job) { user_token ? create(:ci_build, project: project, user: user, status: :running) : double(token: 'wrong') }
let(:headers) { user_role == :anonymous ? {} : job_basic_auth_header(job) }
+ let(:snowplow_gitlab_standard_context) { snowplow_context(user_role: user_role) }
subject { get api(url), headers: headers }
@@ -140,6 +142,7 @@ RSpec.shared_examples 'handling nuget metadata requests with package name' do |e
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
+ let(:snowplow_gitlab_standard_context) { snowplow_context(user_role: user_role) }
subject { get api(url), headers: headers }
@@ -207,6 +210,7 @@ RSpec.shared_examples 'handling nuget metadata requests with package name and pa
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
+ let(:snowplow_gitlab_standard_context) { snowplow_context(user_role: user_role) }
subject { get api(url), headers: headers }
@@ -277,6 +281,7 @@ RSpec.shared_examples 'handling nuget search requests' do |example_names_with_st
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
+ let(:snowplow_gitlab_standard_context) { snowplow_context(user_role: user_role) }
subject { get api(url), headers: headers }
diff --git a/spec/support/shared_examples/requests/api/packages_shared_examples.rb b/spec/support/shared_examples/requests/api/packages_shared_examples.rb
index 98264baa61d..3168f25e4fa 100644
--- a/spec/support/shared_examples/requests/api/packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/packages_shared_examples.rb
@@ -143,37 +143,37 @@ RSpec.shared_examples 'job token for package uploads' do |authorize_endpoint: fa
end
RSpec.shared_examples 'a package tracking event' do |category, action, service_ping_context = true|
- before do
- stub_feature_flags(collect_package_events: true)
- end
-
let(:context) do
- [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll,
- event: snowplow_gitlab_standard_context[:property]).to_h]
+ [
+ Gitlab::Tracking::ServicePingContext.new(
+ data_source: :redis_hll,
+ event: snowplow_gitlab_standard_context[:property]
+ ).to_h
+ ]
end
it "creates a gitlab tracking event #{action}", :snowplow, :aggregate_failures do
- expect { subject }.to change { Packages::Event.count }.by(1)
+ subject
if service_ping_context
- expect_snowplow_event(category: category, action: action,
- label: "redis_hll_counters.user_packages.user_packages_total_unique_counts_monthly",
- context: context, **snowplow_gitlab_standard_context)
+ expect_snowplow_event(
+ category: category,
+ action: action,
+ label: "redis_hll_counters.user_packages.user_packages_total_unique_counts_monthly",
+ context: context,
+ **snowplow_gitlab_standard_context
+ )
else
expect_snowplow_event(category: category, action: action, **snowplow_gitlab_standard_context)
end
end
end
-RSpec.shared_examples 'not a package tracking event' do
- before do
- stub_feature_flags(collect_package_events: true)
- end
-
+RSpec.shared_examples 'not a package tracking event' do |category, action|
it 'does not create a gitlab tracking event', :snowplow, :aggregate_failures do
- expect { subject }.not_to change { Packages::Event.count }
+ subject
- expect_no_snowplow_event
+ expect_no_snowplow_event category: category, action: action
end
end
@@ -183,3 +183,15 @@ RSpec.shared_examples 'bumping the package last downloaded at field' do
.to change { package.reload.last_downloaded_at }.from(nil).to(instance_of(ActiveSupport::TimeWithZone))
end
end
+
+RSpec.shared_examples 'a successful package creation' do
+ it 'creates npm package with file' do
+ expect { subject }
+ .to change { project.packages.count }.by(1)
+ .and change { Packages::PackageFile.count }.by(1)
+ .and change { Packages::Tag.count }.by(1)
+ .and change { Packages::Npm::Metadatum.count }.by(1)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+end
diff --git a/spec/support/shared_examples/requests/api/pipelines/visibility_table_shared_examples.rb b/spec/support/shared_examples/requests/api/pipelines/visibility_table_shared_examples.rb
index 8dd2ef6ccc6..9847ea4e1e2 100644
--- a/spec/support/shared_examples/requests/api/pipelines/visibility_table_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/pipelines/visibility_table_shared_examples.rb
@@ -224,10 +224,10 @@ RSpec.shared_examples 'pipelines visibility table' do
project.project_feature.update!(project_feature_attributes)
project.add_role(ci_user, user_role) if user_role && user_role != :non_member
- get api(pipelines_api_path, api_user)
+ get api(pipelines_api_path, api_user, admin_mode: is_admin)
end
- it do
+ specify do
expect(response).to have_gitlab_http_status(response_status)
expect(api_response).to match(expected_response)
end
diff --git a/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb
index 6065b1163c4..9bd430c3b4f 100644
--- a/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb
@@ -254,6 +254,13 @@ RSpec.shared_examples 'pypi simple API endpoint' do
with_them do
let(:token) { user_token ? personal_access_token.token : 'wrong' }
let(:headers) { user_role == :anonymous ? {} : basic_auth_header(user.username, token) }
+ let(:snowplow_gitlab_standard_context) do
+ if user_role == :anonymous || (visibility_level == :public && !user_token)
+ snowplow_context
+ else
+ snowplow_context.merge(user: user)
+ end
+ end
before do
project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value(visibility_level.to_s))
@@ -269,7 +276,7 @@ RSpec.shared_examples 'pypi simple API endpoint' do
let(:url) { "/projects/#{project.id}/packages/pypi/simple/my-package" }
let(:headers) { basic_auth_header(user.username, personal_access_token.token) }
- let(:snowplow_gitlab_standard_context) { { project: project, namespace: group, property: 'i_package_pypi_user' } }
+ let(:snowplow_gitlab_standard_context) { snowplow_context.merge({ project: project, user: user }) }
it_behaves_like 'PyPI package versions', :developer, :success
end
diff --git a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
index 2154a76d765..3913d29e086 100644
--- a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
@@ -9,7 +9,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
let(:repository_storage_move_id) { storage_move.id }
def get_container_repository_storage_move
- get api(url, user)
+ get api(url, user, admin_mode: user.admin?)
end
it 'returns a container repository storage move', :aggregate_failures do
@@ -39,7 +39,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
shared_examples 'get container repository storage move list' do
def get_container_repository_storage_moves
- get api(url, user)
+ get api(url, user, admin_mode: user.admin?)
end
it 'returns container repository storage moves', :aggregate_failures do
@@ -70,7 +70,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
get_container_repository_storage_moves
- json_ids = json_response.map { |storage_move| storage_move['id'] }
+ json_ids = json_response.pluck('id')
expect(json_ids).to eq([storage_move.id, storage_move_middle.id, storage_move_oldest.id])
end
@@ -90,7 +90,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
let(:container_id) { non_existing_record_id }
it 'returns not found' do
- get api(url, user)
+ get api(url, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -108,7 +108,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
let(:repository_storage_move_id) { storage_move.id }
it 'returns not found' do
- get api(url, user)
+ get api(url, user, admin_mode: user.admin?)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -127,20 +127,20 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
end
end
- describe "POST /#{container_type}/:id/repository_storage_moves" do
+ describe "POST /#{container_type}/:id/repository_storage_moves", :aggregate_failures do
let(:container_id) { container.id }
let(:url) { "/#{container_type}/#{container_id}/repository_storage_moves" }
let(:destination_storage_name) { 'test_second_storage' }
def create_container_repository_storage_move
- post api(url, user), params: { destination_storage_name: destination_storage_name }
+ post api(url, user, admin_mode: user.admin?), params: { destination_storage_name: destination_storage_name }
end
before do
stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/extra_storage' })
end
- it 'schedules a container repository storage move', :aggregate_failures do
+ it 'schedules a container repository storage move' do
create_container_repository_storage_move
storage_move = container.repository_storage_moves.last
@@ -158,7 +158,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
it { expect { create_container_repository_storage_move }.to be_denied_for(:user) }
end
- context 'destination_storage_name is missing', :aggregate_failures do
+ context 'destination_storage_name is missing' do
let(:destination_storage_name) { nil }
it 'schedules a container repository storage move' do
@@ -192,7 +192,7 @@ RSpec.shared_examples 'repository_storage_moves API' do |container_type|
let(:destination_storage_name) { 'test_second_storage' }
def create_container_repository_storage_moves
- post api(url, user), params: {
+ post api(url, user, admin_mode: user.admin?), params: {
source_storage_name: source_storage_name,
destination_storage_name: destination_storage_name
}
diff --git a/spec/support/shared_examples/requests/api/resolvable_discussions_shared_examples.rb b/spec/support/shared_examples/requests/api/resolvable_discussions_shared_examples.rb
index b5139bd8c99..2770e293683 100644
--- a/spec/support/shared_examples/requests/api/resolvable_discussions_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/resolvable_discussions_shared_examples.rb
@@ -71,8 +71,7 @@ RSpec.shared_examples 'resolvable discussions API' do |parent_type, noteable_typ
it 'returns a 404 error when note id not found' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}/notes/#{non_existing_record_id}", user),
- params: { body: 'Hello!' }
+ "discussions/#{note.discussion_id}/notes/#{non_existing_record_id}", user), params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/support/shared_examples/requests/api/snippets_shared_examples.rb b/spec/support/shared_examples/requests/api/snippets_shared_examples.rb
index 1b92eb56f54..56f2394c005 100644
--- a/spec/support/shared_examples/requests/api/snippets_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/snippets_shared_examples.rb
@@ -1,12 +1,19 @@
# frozen_string_literal: true
RSpec.shared_examples 'raw snippet files' do
- let_it_be(:user_token) { create(:personal_access_token, user: snippet.author) }
let(:snippet_id) { snippet.id }
- let(:user) { snippet.author }
+ let_it_be(:user) { snippet.author }
let(:file_path) { '%2Egitattributes' }
let(:ref) { 'master' }
+ let_it_be(:user_token) do
+ if user.admin?
+ create(:personal_access_token, :admin_mode, user: user)
+ else
+ create(:personal_access_token, user: user)
+ end
+ end
+
subject { get api(api_path, personal_access_token: user_token) }
context 'with an invalid snippet ID' do
@@ -15,8 +22,10 @@ RSpec.shared_examples 'raw snippet files' do
it 'returns 404' do
subject
- expect(response).to have_gitlab_http_status(:not_found)
- expect(json_response['message']).to eq('404 Snippet Not Found')
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['message']).to eq('404 Snippet Not Found')
+ end
end
end
@@ -185,7 +194,7 @@ RSpec.shared_examples 'snippet individual non-file updates' do
end
RSpec.shared_examples 'invalid snippet updates' do
- it 'returns 404 for invalid snippet id' do
+ it 'returns 404 for invalid snippet id', :aggregate_failures do
update_snippet(snippet_id: non_existing_record_id, params: { title: 'foo' })
expect(response).to have_gitlab_http_status(:not_found)
@@ -204,7 +213,7 @@ RSpec.shared_examples 'invalid snippet updates' do
expect(response).to have_gitlab_http_status(:bad_request)
end
- it 'returns 400 if title is blank' do
+ it 'returns 400 if title is blank', :aggregate_failures do
update_snippet(params: { title: '' })
expect(response).to have_gitlab_http_status(:bad_request)
@@ -236,7 +245,9 @@ RSpec.shared_examples 'snippet access with different users' do
it 'returns the correct response' do
request_user = user_for(requester)
- get api(path, request_user)
+ admin_mode = requester == :admin
+
+ get api(path, request_user, admin_mode: admin_mode)
expect(response).to have_gitlab_http_status(status)
end
@@ -250,8 +261,6 @@ RSpec.shared_examples 'snippet access with different users' do
other_user
when :admin
admin
- else
- nil
end
end
diff --git a/spec/support/shared_examples/requests/api/status_shared_examples.rb b/spec/support/shared_examples/requests/api/status_shared_examples.rb
index 40843ccbd15..ff3947c0e73 100644
--- a/spec/support/shared_examples/requests/api/status_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/status_shared_examples.rb
@@ -21,6 +21,23 @@ RSpec.shared_examples '400 response' do
end
end
+RSpec.shared_examples '401 response' do
+ let(:message) { nil }
+
+ before do
+ # Fires the request
+ request
+ end
+
+ it 'returns 401' do
+ expect(response).to have_gitlab_http_status(:unauthorized)
+
+ if message.present?
+ expect(json_response['message']).to eq(message)
+ end
+ end
+end
+
RSpec.shared_examples '403 response' do
before do
# Fires the request
@@ -54,7 +71,7 @@ RSpec.shared_examples '412 response' do
let(:params) { nil }
let(:success_status) { 204 }
- context 'for a modified ressource' do
+ context 'for a modified resource' do
before do
delete request, params: params, headers: { 'HTTP_IF_UNMODIFIED_SINCE' => '1990-01-12T00:00:48-0600' }
end
@@ -65,7 +82,7 @@ RSpec.shared_examples '412 response' do
end
end
- context 'for an unmodified ressource' do
+ context 'for an unmodified resource' do
before do
delete request, params: params, headers: { 'HTTP_IF_UNMODIFIED_SINCE' => Time.now }
end
diff --git a/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb b/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb
index 86a1fd76d09..398421c7a79 100644
--- a/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb
@@ -173,8 +173,7 @@ RSpec.shared_examples 'time tracking endpoints' do |issuable_name|
describe "GET /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_stats" do
it "returns the time stats for #{issuable_name}" do
- issuable.update!(spend_time: { duration: 1800, user_id: user.id },
- time_estimate: 3600)
+ issuable.update!(spend_time: { duration: 1800, user_id: user.id }, time_estimate: 3600)
get api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_stats", user)