summaryrefslogtreecommitdiff
path: root/spec/lib/api
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/api')
-rw-r--r--spec/lib/api/api_spec.rb2
-rw-r--r--spec/lib/api/entities/branch_spec.rb2
-rw-r--r--spec/lib/api/entities/deploy_key_spec.rb2
-rw-r--r--spec/lib/api/entities/deploy_keys_project_spec.rb2
-rw-r--r--spec/lib/api/entities/design_management/design_spec.rb2
-rw-r--r--spec/lib/api/entities/job_request/image_spec.rb2
-rw-r--r--spec/lib/api/entities/job_request/port_spec.rb2
-rw-r--r--spec/lib/api/entities/merge_request_approvals_spec.rb36
-rw-r--r--spec/lib/api/entities/merge_request_basic_spec.rb43
-rw-r--r--spec/lib/api/entities/nuget/dependency_group_spec.rb50
-rw-r--r--spec/lib/api/entities/nuget/dependency_spec.rb28
-rw-r--r--spec/lib/api/entities/nuget/metadatum_spec.rb35
-rw-r--r--spec/lib/api/entities/nuget/package_metadata_catalog_entry_spec.rb43
-rw-r--r--spec/lib/api/entities/nuget/search_result_spec.rb57
-rw-r--r--spec/lib/api/entities/project_import_failed_relation_spec.rb2
-rw-r--r--spec/lib/api/entities/project_import_status_spec.rb2
-rw-r--r--spec/lib/api/entities/project_repository_storage_move_spec.rb2
-rw-r--r--spec/lib/api/entities/release_spec.rb2
-rw-r--r--spec/lib/api/entities/snippet_spec.rb55
-rw-r--r--spec/lib/api/entities/ssh_key_spec.rb2
-rw-r--r--spec/lib/api/entities/user_spec.rb2
-rw-r--r--spec/lib/api/helpers/common_helpers_spec.rb51
-rw-r--r--spec/lib/api/helpers/graphql_helpers_spec.rb2
-rw-r--r--spec/lib/api/helpers/label_helpers_spec.rb2
-rw-r--r--spec/lib/api/helpers/packages/dependency_proxy_helpers_spec.rb72
-rw-r--r--spec/lib/api/helpers/packages_helpers_spec.rb104
-rw-r--r--spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb154
-rw-r--r--spec/lib/api/helpers/pagination_spec.rb2
-rw-r--r--spec/lib/api/helpers/pagination_strategies_spec.rb2
-rw-r--r--spec/lib/api/helpers/related_resources_helpers_spec.rb2
-rw-r--r--spec/lib/api/helpers/version_spec.rb2
-rw-r--r--spec/lib/api/helpers_spec.rb2
-rw-r--r--spec/lib/api/support/git_access_actor_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/absence_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/array_none_any_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/file_path_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/git_ref_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/git_sha_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/integer_none_any_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/limit_spec.rb2
-rw-r--r--spec/lib/api/validations/validators/untrusted_regexp_spec.rb2
41 files changed, 756 insertions, 30 deletions
diff --git a/spec/lib/api/api_spec.rb b/spec/lib/api/api_spec.rb
index c83d068ca50..cf08eaa7653 100644
--- a/spec/lib/api/api_spec.rb
+++ b/spec/lib/api/api_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::API do
+RSpec.describe API::API do
describe '.prefix' do
it 'has a prefix defined' do
expect(described_class.prefix).to eq :api
diff --git a/spec/lib/api/entities/branch_spec.rb b/spec/lib/api/entities/branch_spec.rb
index 604f56c0cb2..e07b431964c 100644
--- a/spec/lib/api/entities/branch_spec.rb
+++ b/spec/lib/api/entities/branch_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::Branch do
+RSpec.describe API::Entities::Branch do
describe '#as_json' do
subject { entity.as_json }
diff --git a/spec/lib/api/entities/deploy_key_spec.rb b/spec/lib/api/entities/deploy_key_spec.rb
index 704dabae63b..6427d6eac8f 100644
--- a/spec/lib/api/entities/deploy_key_spec.rb
+++ b/spec/lib/api/entities/deploy_key_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::DeployKey do
+RSpec.describe API::Entities::DeployKey do
describe '#as_json' do
subject { entity.as_json }
diff --git a/spec/lib/api/entities/deploy_keys_project_spec.rb b/spec/lib/api/entities/deploy_keys_project_spec.rb
index a357467d7ce..57ffdc55736 100644
--- a/spec/lib/api/entities/deploy_keys_project_spec.rb
+++ b/spec/lib/api/entities/deploy_keys_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::DeployKeysProject do
+RSpec.describe API::Entities::DeployKeysProject do
describe '#as_json' do
subject { entity.as_json }
diff --git a/spec/lib/api/entities/design_management/design_spec.rb b/spec/lib/api/entities/design_management/design_spec.rb
index 50ca3b43c6a..fe449e3e9bc 100644
--- a/spec/lib/api/entities/design_management/design_spec.rb
+++ b/spec/lib/api/entities/design_management/design_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::DesignManagement::Design do
+RSpec.describe API::Entities::DesignManagement::Design do
let_it_be(:design) { create(:design) }
let(:entity) { described_class.new(design, request: double) }
diff --git a/spec/lib/api/entities/job_request/image_spec.rb b/spec/lib/api/entities/job_request/image_spec.rb
index 092c181ae9c..f13eab6a752 100644
--- a/spec/lib/api/entities/job_request/image_spec.rb
+++ b/spec/lib/api/entities/job_request/image_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::JobRequest::Image do
+RSpec.describe API::Entities::JobRequest::Image do
let(:ports) { [{ number: 80, protocol: 'http', name: 'name' }]}
let(:image) { double(name: 'image_name', entrypoint: ['foo'], ports: ports)}
let(:entity) { described_class.new(image) }
diff --git a/spec/lib/api/entities/job_request/port_spec.rb b/spec/lib/api/entities/job_request/port_spec.rb
index 40ab4cd6231..4820c4a691b 100644
--- a/spec/lib/api/entities/job_request/port_spec.rb
+++ b/spec/lib/api/entities/job_request/port_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::API::Entities::JobRequest::Port do
+RSpec.describe ::API::Entities::JobRequest::Port do
let(:port) { double(number: 80, protocol: 'http', name: 'name')}
let(:entity) { described_class.new(port) }
diff --git a/spec/lib/api/entities/merge_request_approvals_spec.rb b/spec/lib/api/entities/merge_request_approvals_spec.rb
new file mode 100644
index 00000000000..cbbb037100a
--- /dev/null
+++ b/spec/lib/api/entities/merge_request_approvals_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::MergeRequestApprovals do
+ let(:user) { create(:user) }
+ let(:merge_request) { create(:merge_request) }
+
+ subject { described_class.new(merge_request, current_user: user).as_json }
+
+ before do
+ merge_request.project.add_developer(user)
+ end
+
+ it 'serializes an approved merge request' do
+ create(:approval, merge_request: merge_request, user: user)
+
+ is_expected.to eq({
+ user_has_approved: true,
+ user_can_approve: false,
+ approved: true,
+ approved_by: [{
+ user: API::Entities::UserBasic.new(user).as_json
+ }]
+ })
+ end
+
+ it 'serializes a merge request that is not approved' do
+ is_expected.to eq({
+ user_has_approved: false,
+ user_can_approve: true,
+ approved: false,
+ approved_by: []
+ })
+ end
+end
diff --git a/spec/lib/api/entities/merge_request_basic_spec.rb b/spec/lib/api/entities/merge_request_basic_spec.rb
new file mode 100644
index 00000000000..715fcf4bcdb
--- /dev/null
+++ b/spec/lib/api/entities/merge_request_basic_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::API::Entities::MergeRequestBasic do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:merge_request) { create(:merge_request) }
+ let_it_be(:labels) { create_list(:label, 3) }
+ let_it_be(:merge_requests) { create_list(:labeled_merge_request, 10, :unique_branches, :with_diffs, labels: labels) }
+
+ # This mimics the behavior of the `Grape::Entity` serializer
+ def present(obj)
+ described_class.new(obj).presented
+ end
+
+ context "with :with_api_entity_associations scope" do
+ let(:scope) { MergeRequest.with_api_entity_associations }
+
+ it "avoids N+1 queries" do
+ query = scope.find(merge_request.id)
+
+ control = ActiveRecord::QueryRecorder.new do
+ present(query).to_json
+ end
+
+ # stub the `head_commit_sha` as it will trigger a
+ # backward compatibility query that is out-of-scope
+ # for this test whenever it is `nil`
+ allow_any_instance_of(MergeRequestDiff).to receive(:head_commit_sha).and_return(Gitlab::Git::BLANK_SHA)
+
+ query = scope.all
+ batch = ActiveRecord::QueryRecorder.new do
+ entities = query.map(&method(:present))
+
+ entities.to_json
+ end
+
+ # The current threshold is 3 query per entity maximum.
+ expect(batch.count).to be_within(3 * query.count).of(control.count)
+ end
+ end
+end
diff --git a/spec/lib/api/entities/nuget/dependency_group_spec.rb b/spec/lib/api/entities/nuget/dependency_group_spec.rb
new file mode 100644
index 00000000000..5a649be846b
--- /dev/null
+++ b/spec/lib/api/entities/nuget/dependency_group_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Nuget::DependencyGroup do
+ let(:dependency_group) do
+ {
+ id: 'http://gitlab.com/Sandbox.App/1.0.0.json#dependencygroup',
+ type: 'PackageDependencyGroup',
+ target_framework: 'fwk test',
+ dependencies: [
+ {
+ id: 'http://gitlab.com/Sandbox.App/1.0.0.json#dependency',
+ type: 'PackageDependency',
+ name: 'Dependency',
+ range: '2.0.0'
+ }
+ ]
+ }
+ end
+
+ let(:expected) do
+ {
+ '@id': 'http://gitlab.com/Sandbox.App/1.0.0.json#dependencygroup',
+ '@type': 'PackageDependencyGroup',
+ 'targetFramework': 'fwk test',
+ 'dependencies': [
+ {
+ '@id': 'http://gitlab.com/Sandbox.App/1.0.0.json#dependency',
+ '@type': 'PackageDependency',
+ 'id': 'Dependency',
+ 'range': '2.0.0'
+ }
+ ]
+ }
+ end
+ let(:entity) { described_class.new(dependency_group) }
+
+ subject { entity.as_json }
+
+ it { is_expected.to eq(expected) }
+
+ context 'dependency group without target framework' do
+ let(:dependency_group_with_no_target_framework) { dependency_group.tap { |dg| dg[:target_framework] = nil } }
+ let(:expected_no_target_framework) { expected.except(:targetFramework) }
+ let(:entity) { described_class.new(dependency_group_with_no_target_framework) }
+
+ it { is_expected.to eq(expected_no_target_framework) }
+ end
+end
diff --git a/spec/lib/api/entities/nuget/dependency_spec.rb b/spec/lib/api/entities/nuget/dependency_spec.rb
new file mode 100644
index 00000000000..13897cc91f0
--- /dev/null
+++ b/spec/lib/api/entities/nuget/dependency_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Nuget::Dependency do
+ let(:dependency) do
+ {
+ id: 'http://gitlab.com/Sandbox.App/1.0.0.json#dependency',
+ type: 'PackageDependency',
+ name: 'Dependency',
+ range: '2.0.0'
+ }
+ end
+
+ let(:expected) do
+ {
+ '@id': 'http://gitlab.com/Sandbox.App/1.0.0.json#dependency',
+ '@type': 'PackageDependency',
+ 'id': 'Dependency',
+ 'range': '2.0.0'
+ }
+ end
+ let(:entity) { described_class.new(dependency) }
+
+ subject { entity.as_json }
+
+ it { is_expected.to eq(expected) }
+end
diff --git a/spec/lib/api/entities/nuget/metadatum_spec.rb b/spec/lib/api/entities/nuget/metadatum_spec.rb
new file mode 100644
index 00000000000..fe94ea3a69a
--- /dev/null
+++ b/spec/lib/api/entities/nuget/metadatum_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Nuget::Metadatum do
+ let(:metadatum) do
+ {
+ project_url: 'http://sandbox.com/project',
+ license_url: 'http://sandbox.com/license',
+ icon_url: 'http://sandbox.com/icon'
+ }
+ end
+ let(:expected) do
+ {
+ 'projectUrl': 'http://sandbox.com/project',
+ 'licenseUrl': 'http://sandbox.com/license',
+ 'iconUrl': 'http://sandbox.com/icon'
+ }
+ end
+ let(:entity) { described_class.new(metadatum) }
+
+ subject { entity.as_json }
+
+ it { is_expected.to eq(expected) }
+
+ %i[project_url license_url icon_url].each do |optional_field|
+ context "metadatum without #{optional_field}" do
+ let(:metadatum_without_a_field) { metadatum.except(optional_field) }
+ let(:expected_without_a_field) { expected.except(optional_field.to_s.camelize(:lower).to_sym) }
+ let(:entity) { described_class.new(metadatum_without_a_field) }
+
+ it { is_expected.to eq(expected_without_a_field) }
+ end
+ end
+end
diff --git a/spec/lib/api/entities/nuget/package_metadata_catalog_entry_spec.rb b/spec/lib/api/entities/nuget/package_metadata_catalog_entry_spec.rb
new file mode 100644
index 00000000000..c422b51bf3b
--- /dev/null
+++ b/spec/lib/api/entities/nuget/package_metadata_catalog_entry_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Nuget::PackageMetadataCatalogEntry do
+ let(:entry) do
+ {
+ json_url: 'http://sandbox.com/json/package',
+ authors: 'Authors',
+ dependency_groups: [],
+ package_name: 'PackageTest',
+ package_version: '1.2.3',
+ tags: 'tag1 tag2 tag3',
+ archive_url: 'http://sandbox.com/archive/package',
+ summary: 'Summary',
+ metadatum: {
+ project_url: 'http://sandbox.com/project',
+ license_url: 'http://sandbox.com/license',
+ icon_url: 'http://sandbox.com/icon'
+ }
+ }
+ end
+
+ let(:expected) do
+ {
+ '@id': 'http://sandbox.com/json/package',
+ 'id': 'PackageTest',
+ 'version': '1.2.3',
+ 'authors': 'Authors',
+ 'dependencyGroups': [],
+ 'tags': 'tag1 tag2 tag3',
+ 'packageContent': 'http://sandbox.com/archive/package',
+ 'summary': 'Summary',
+ 'projectUrl': 'http://sandbox.com/project',
+ 'licenseUrl': 'http://sandbox.com/license',
+ 'iconUrl': 'http://sandbox.com/icon'
+ }
+ end
+
+ subject { described_class.new(entry).as_json }
+
+ it { is_expected.to eq(expected) }
+end
diff --git a/spec/lib/api/entities/nuget/search_result_spec.rb b/spec/lib/api/entities/nuget/search_result_spec.rb
new file mode 100644
index 00000000000..2a760c70224
--- /dev/null
+++ b/spec/lib/api/entities/nuget/search_result_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Nuget::SearchResult do
+ let(:search_result) do
+ {
+ type: 'Package',
+ authors: 'Author',
+ name: 'PackageTest',
+ version: '1.2.3',
+ versions: [
+ {
+ json_url: 'http://sandbox.com/json/package',
+ downloads: 100,
+ version: '1.2.3'
+ }
+ ],
+ summary: 'Summary',
+ total_downloads: 100,
+ verified: true,
+ tags: 'tag1 tag2 tag3',
+ metadatum: {
+ project_url: 'http://sandbox.com/project',
+ license_url: 'http://sandbox.com/license',
+ icon_url: 'http://sandbox.com/icon'
+ }
+ }
+ end
+ let(:expected) do
+ {
+ '@type': 'Package',
+ 'authors': 'Author',
+ 'id': 'PackageTest',
+ 'title': 'PackageTest',
+ 'summary': 'Summary',
+ 'totalDownloads': 100,
+ 'verified': true,
+ 'version': '1.2.3',
+ 'tags': 'tag1 tag2 tag3',
+ 'projectUrl': 'http://sandbox.com/project',
+ 'licenseUrl': 'http://sandbox.com/license',
+ 'iconUrl': 'http://sandbox.com/icon',
+ 'versions': [
+ {
+ '@id': 'http://sandbox.com/json/package',
+ 'downloads': 100,
+ 'version': '1.2.3'
+ }
+ ]
+ }
+ end
+
+ subject { described_class.new(search_result).as_json }
+
+ it { is_expected.to eq(expected) }
+end
diff --git a/spec/lib/api/entities/project_import_failed_relation_spec.rb b/spec/lib/api/entities/project_import_failed_relation_spec.rb
index f8330713480..51a684c4564 100644
--- a/spec/lib/api/entities/project_import_failed_relation_spec.rb
+++ b/spec/lib/api/entities/project_import_failed_relation_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::ProjectImportFailedRelation do
+RSpec.describe API::Entities::ProjectImportFailedRelation do
describe '#as_json' do
subject { entity.as_json }
diff --git a/spec/lib/api/entities/project_import_status_spec.rb b/spec/lib/api/entities/project_import_status_spec.rb
index a800d703496..5eda613a6a6 100644
--- a/spec/lib/api/entities/project_import_status_spec.rb
+++ b/spec/lib/api/entities/project_import_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::ProjectImportStatus do
+RSpec.describe API::Entities::ProjectImportStatus do
describe '#as_json' do
subject { entity.as_json }
diff --git a/spec/lib/api/entities/project_repository_storage_move_spec.rb b/spec/lib/api/entities/project_repository_storage_move_spec.rb
index 1c38c8231d4..b0102dc376a 100644
--- a/spec/lib/api/entities/project_repository_storage_move_spec.rb
+++ b/spec/lib/api/entities/project_repository_storage_move_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::ProjectRepositoryStorageMove do
+RSpec.describe API::Entities::ProjectRepositoryStorageMove do
describe '#as_json' do
subject { entity.as_json }
diff --git a/spec/lib/api/entities/release_spec.rb b/spec/lib/api/entities/release_spec.rb
index fa9e1e74f9b..d57c283c1f4 100644
--- a/spec/lib/api/entities/release_spec.rb
+++ b/spec/lib/api/entities/release_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::Release do
+RSpec.describe API::Entities::Release do
let_it_be(:project) { create(:project) }
let(:release) { create(:release, project: project) }
let(:evidence) { release.evidences.first }
diff --git a/spec/lib/api/entities/snippet_spec.rb b/spec/lib/api/entities/snippet_spec.rb
index dada0942e49..bcb8c364392 100644
--- a/spec/lib/api/entities/snippet_spec.rb
+++ b/spec/lib/api/entities/snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ::API::Entities::Snippet do
+RSpec.describe ::API::Entities::Snippet do
let_it_be(:user) { create(:user) }
let_it_be(:personal_snippet) { create(:personal_snippet, :repository, author: user ) }
let_it_be(:project_snippet) { create(:project_snippet, :repository, author: user) }
@@ -21,6 +21,16 @@ describe ::API::Entities::Snippet do
it { expect(subject[:visibility]).to eq snippet.visibility }
it { expect(subject).to include(:author) }
+ context 'with snippet_multiple_files feature disabled' do
+ before do
+ stub_feature_flags(snippet_multiple_files: false)
+ end
+
+ it 'does not return files' do
+ expect(subject).not_to include(:files)
+ end
+ end
+
describe 'file_name' do
it 'returns attribute from repository' do
expect(subject[:file_name]).to eq snippet.blobs.first.path
@@ -62,6 +72,49 @@ describe ::API::Entities::Snippet do
end
end
end
+
+ describe 'files' do
+ let(:blob) { snippet.blobs.first }
+ let(:ref) { blob.repository.root_ref }
+
+ context 'when repository does not exist' do
+ it 'does not include the files attribute' do
+ allow(snippet).to receive(:repository_exists?).and_return(false)
+
+ expect(subject).not_to include(:files)
+ end
+ end
+
+ shared_examples 'snippet files' do
+ let(:file) { subject[:files].first }
+
+ it 'returns all snippet files' do
+ expect(subject[:files].count).to eq snippet.blobs.count
+ end
+
+ it 'has the file path' do
+ expect(file[:path]).to eq blob.path
+ end
+
+ it 'has the raw url' do
+ expect(file[:raw_url]).to match(raw_url)
+ end
+ end
+
+ context 'with PersonalSnippet' do
+ it_behaves_like 'snippet files' do
+ let(:snippet) { personal_snippet }
+ let(:raw_url) { "/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}" }
+ end
+ end
+
+ context 'with ProjectSnippet' do
+ it_behaves_like 'snippet files' do
+ let(:snippet) { project_snippet }
+ let(:raw_url) { "#{snippet.project.full_path}/-/snippets/#{snippet.id}/raw/#{ref}/#{blob.path}" }
+ end
+ end
+ end
end
context 'with PersonalSnippet' do
diff --git a/spec/lib/api/entities/ssh_key_spec.rb b/spec/lib/api/entities/ssh_key_spec.rb
index 25a0fecfb75..768ad416fbe 100644
--- a/spec/lib/api/entities/ssh_key_spec.rb
+++ b/spec/lib/api/entities/ssh_key_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::SSHKey do
+RSpec.describe API::Entities::SSHKey do
describe '#as_json' do
subject { entity.as_json }
diff --git a/spec/lib/api/entities/user_spec.rb b/spec/lib/api/entities/user_spec.rb
index 20524b197e0..99ffe0eb925 100644
--- a/spec/lib/api/entities/user_spec.rb
+++ b/spec/lib/api/entities/user_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Entities::User do
+RSpec.describe API::Entities::User do
let(:user) { create(:user) }
let(:current_user) { create(:user) }
diff --git a/spec/lib/api/helpers/common_helpers_spec.rb b/spec/lib/api/helpers/common_helpers_spec.rb
new file mode 100644
index 00000000000..5162d2f1000
--- /dev/null
+++ b/spec/lib/api/helpers/common_helpers_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Helpers::CommonHelpers do
+ include Rack::Test::Methods
+
+ subject do
+ Class.new(Grape::API) do
+ helpers API::Helpers::CommonHelpers
+
+ before do
+ coerce_nil_params_to_array!
+ end
+
+ params do
+ requires :id, type: String
+ optional :array, type: Array, coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce
+ optional :array_of_strings, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce
+ optional :array_of_ints, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce
+ end
+ get ":id" do
+ params.to_json
+ end
+ end
+ end
+
+ def app
+ subject
+ end
+
+ describe '.coerce_nil_params_to_array!' do
+ let(:json_response) { Gitlab::Json.parse(last_response.body) }
+
+ it 'converts all nil parameters to empty arrays' do
+ get '/test?array=&array_of_strings=&array_of_ints='
+
+ expect(json_response['array']).to eq([])
+ expect(json_response['array_of_strings']).to eq([])
+ expect(json_response['array_of_ints']).to eq([])
+ end
+
+ it 'leaves non-nil parameters alone' do
+ get '/test?array=&array_of_strings=test,me&array_of_ints=1,2'
+
+ expect(json_response['array']).to eq([])
+ expect(json_response['array_of_strings']).to eq(%w(test me))
+ expect(json_response['array_of_ints']).to eq([1, 2])
+ end
+ end
+end
diff --git a/spec/lib/api/helpers/graphql_helpers_spec.rb b/spec/lib/api/helpers/graphql_helpers_spec.rb
index c775ba6d5e8..678f4f8a3e3 100644
--- a/spec/lib/api/helpers/graphql_helpers_spec.rb
+++ b/spec/lib/api/helpers/graphql_helpers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Helpers::GraphqlHelpers do
+RSpec.describe API::Helpers::GraphqlHelpers do
describe 'run_graphql!' do
let(:query) { '{ metadata { version } }' }
diff --git a/spec/lib/api/helpers/label_helpers_spec.rb b/spec/lib/api/helpers/label_helpers_spec.rb
index 138e9a22d70..007cb3248e2 100644
--- a/spec/lib/api/helpers/label_helpers_spec.rb
+++ b/spec/lib/api/helpers/label_helpers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Helpers::LabelHelpers do
+RSpec.describe API::Helpers::LabelHelpers do
describe 'create_service_params' do
let(:label_helper) do
Class.new do
diff --git a/spec/lib/api/helpers/packages/dependency_proxy_helpers_spec.rb b/spec/lib/api/helpers/packages/dependency_proxy_helpers_spec.rb
new file mode 100644
index 00000000000..ccf96bcbad6
--- /dev/null
+++ b/spec/lib/api/helpers/packages/dependency_proxy_helpers_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Helpers::Packages::DependencyProxyHelpers do
+ let_it_be(:helper) { Class.new.include(described_class).new }
+
+ describe 'redirect_registry_request' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:options) { {} }
+
+ subject { helper.redirect_registry_request(forward_to_registry, package_type, options) { helper.fallback } }
+
+ shared_examples 'executing fallback' do
+ it 'redirects to package registry' do
+ expect(helper).to receive(:registry_url).never
+ expect(helper).to receive(:redirect).never
+ expect(helper).to receive(:fallback).once
+
+ subject
+ end
+ end
+
+ shared_examples 'executing redirect' do
+ it 'redirects to package registry' do
+ expect(helper).to receive(:registry_url).once
+ expect(helper).to receive(:redirect).once
+ expect(helper).to receive(:fallback).never
+
+ subject
+ end
+ end
+
+ context 'with npm packages' do
+ let(:package_type) { :npm }
+
+ where(:application_setting, :forward_to_registry, :example_name) do
+ true | true | 'executing redirect'
+ true | false | 'executing fallback'
+ false | true | 'executing fallback'
+ false | false | 'executing fallback'
+ end
+
+ with_them do
+ before do
+ stub_application_setting(npm_package_requests_forwarding: application_setting)
+ end
+
+ it_behaves_like params[:example_name]
+ end
+ end
+
+ context 'with non-forwardable packages' do
+ let(:forward_to_registry) { true }
+
+ before do
+ stub_application_setting(npm_package_requests_forwarding: true)
+ end
+
+ Packages::Package.package_types.keys.without('npm').each do |pkg_type|
+ context "#{pkg_type}" do
+ let(:package_type) { pkg_type }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(ArgumentError, "Can't build registry_url for package_type #{package_type}")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/api/helpers/packages_helpers_spec.rb b/spec/lib/api/helpers/packages_helpers_spec.rb
new file mode 100644
index 00000000000..0c51e25bad9
--- /dev/null
+++ b/spec/lib/api/helpers/packages_helpers_spec.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Helpers::PackagesHelpers do
+ let_it_be(:helper) { Class.new.include(described_class).new }
+ let_it_be(:project) { create(:project) }
+
+ describe 'authorize_packages_access!' do
+ subject { helper.authorize_packages_access!(project) }
+
+ it 'authorizes packages access' do
+ expect(helper).to receive(:require_packages_enabled!)
+ expect(helper).to receive(:authorize_read_package!).with(project)
+
+ expect(subject).to eq nil
+ end
+ end
+
+ %i[read_package create_package destroy_package].each do |action|
+ describe "authorize_#{action}!" do
+ subject { helper.send("authorize_#{action}!", project) }
+
+ it 'calls authorize!' do
+ expect(helper).to receive(:authorize!).with(action, project)
+
+ expect(subject).to eq nil
+ end
+ end
+ end
+
+ describe 'require_packages_enabled!' do
+ let(:packages_enabled) { true }
+
+ subject { helper.require_packages_enabled! }
+
+ before do
+ allow(::Gitlab.config.packages).to receive(:enabled).and_return(packages_enabled)
+ end
+
+ context 'with packages enabled' do
+ it "doesn't call not_found!" do
+ expect(helper).to receive(:not_found!).never
+
+ expect(subject).to eq nil
+ end
+ end
+
+ context 'with package disabled' do
+ let(:packages_enabled) { false }
+
+ it 'calls not_found!' do
+ expect(helper).to receive(:not_found!).once
+
+ subject
+ end
+ end
+ end
+
+ describe '#authorize_workhorse!' do
+ let_it_be(:headers) { {} }
+
+ subject { helper.authorize_workhorse!(subject: project) }
+
+ before do
+ allow(helper).to receive(:headers).and_return(headers)
+ end
+
+ it 'authorizes workhorse' do
+ expect(helper).to receive(:authorize_upload!).with(project)
+ expect(helper).to receive(:status).with(200)
+ expect(helper).to receive(:content_type).with(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(Gitlab::Workhorse).to receive(:verify_api_request!).with(headers)
+ expect(::Packages::PackageFileUploader).to receive(:workhorse_authorize).with(has_length: true)
+
+ expect(subject).to eq nil
+ end
+
+ context 'without length' do
+ subject { helper.authorize_workhorse!(subject: project, has_length: false) }
+
+ it 'authorizes workhorse' do
+ expect(helper).to receive(:authorize_upload!).with(project)
+ expect(helper).to receive(:status).with(200)
+ expect(helper).to receive(:content_type).with(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE)
+ expect(Gitlab::Workhorse).to receive(:verify_api_request!).with(headers)
+ expect(::Packages::PackageFileUploader).to receive(:workhorse_authorize).with(has_length: false, maximum_size: ::API::Helpers::PackagesHelpers::MAX_PACKAGE_FILE_SIZE)
+
+ expect(subject).to eq nil
+ end
+ end
+ end
+
+ describe '#authorize_upload!' do
+ subject { helper.authorize_upload!(project) }
+
+ it 'authorizes the upload' do
+ expect(helper).to receive(:authorize_create_package!).with(project)
+ expect(helper).to receive(:require_gitlab_workhorse!)
+
+ expect(subject).to eq nil
+ end
+ end
+end
diff --git a/spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb b/spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb
new file mode 100644
index 00000000000..80be5f7d10a
--- /dev/null
+++ b/spec/lib/api/helpers/packages_manager_clients_helpers_spec.rb
@@ -0,0 +1,154 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Helpers::PackagesManagerClientsHelpers do
+ let_it_be(:personal_access_token) { create(:personal_access_token) }
+ let_it_be(:username) { personal_access_token.user.username }
+ let_it_be(:helper) { Class.new.include(described_class).new }
+ let(:password) { personal_access_token.token }
+
+ describe '#find_personal_access_token_from_http_basic_auth' do
+ let(:headers) { { Authorization: basic_http_auth(username, password) } }
+
+ subject { helper.find_personal_access_token_from_http_basic_auth }
+
+ before do
+ allow(helper).to receive(:headers).and_return(headers&.with_indifferent_access)
+ end
+
+ context 'with a valid Authorization header' do
+ it { is_expected.to eq personal_access_token }
+ end
+
+ context 'with an invalid Authorization header' do
+ where(:headers) do
+ [
+ [{ Authorization: 'Invalid' }],
+ [{}],
+ [nil]
+ ]
+ end
+
+ with_them do
+ it { is_expected.to be nil }
+ end
+ end
+
+ context 'with an unknown Authorization header' do
+ let(:password) { 'Unknown' }
+
+ it { is_expected.to be nil }
+ end
+ end
+
+ describe '#find_job_from_http_basic_auth' do
+ let_it_be(:user) { personal_access_token.user }
+
+ let(:job) { create(:ci_build, user: user) }
+ let(:password) { job.token }
+ let(:headers) { { Authorization: basic_http_auth(username, password) } }
+
+ subject { helper.find_job_from_http_basic_auth }
+
+ before do
+ allow(helper).to receive(:headers).and_return(headers&.with_indifferent_access)
+ end
+
+ context 'with a valid Authorization header' do
+ it { is_expected.to eq job }
+ end
+
+ context 'with an invalid Authorization header' do
+ where(:headers) do
+ [
+ [{ Authorization: 'Invalid' }],
+ [{}],
+ [nil]
+ ]
+ end
+
+ with_them do
+ it { is_expected.to be nil }
+ end
+ end
+
+ context 'with an unknown Authorization header' do
+ let(:password) { 'Unknown' }
+
+ it { is_expected.to be nil }
+ end
+ end
+
+ describe '#find_deploy_token_from_http_basic_auth' do
+ let_it_be(:deploy_token) { create(:deploy_token) }
+ let(:token) { deploy_token.token }
+ let(:headers) { { Authorization: basic_http_auth(deploy_token.username, token) } }
+
+ subject { helper.find_deploy_token_from_http_basic_auth }
+
+ before do
+ allow(helper).to receive(:headers).and_return(headers&.with_indifferent_access)
+ end
+
+ context 'with a valid Authorization header' do
+ it { is_expected.to eq deploy_token }
+ end
+
+ context 'with an invalid Authorization header' do
+ where(:headers) do
+ [
+ [{ Authorization: 'Invalid' }],
+ [{}],
+ [nil]
+ ]
+ end
+
+ with_them do
+ it { is_expected.to be nil }
+ end
+ end
+
+ context 'with an invalid token' do
+ let(:token) { 'Unknown' }
+
+ it { is_expected.to be nil }
+ end
+ end
+
+ describe '#uploaded_package_file' do
+ let_it_be(:params) { {} }
+
+ subject { helper.uploaded_package_file }
+
+ before do
+ allow(helper).to receive(:params).and_return(params)
+ end
+
+ context 'with valid uploaded package file' do
+ let_it_be(:uploaded_file) { Object.new }
+
+ before do
+ allow(UploadedFile).to receive(:from_params).and_return(uploaded_file)
+ end
+
+ it { is_expected.to be uploaded_file }
+ end
+
+ context 'with invalid uploaded package file' do
+ before do
+ allow(UploadedFile).to receive(:from_params).and_return(nil)
+ end
+
+ it 'fails with bad_request!' do
+ expect(helper).to receive(:bad_request!)
+
+ expect(subject).to be nil
+ end
+ end
+ end
+
+ def basic_http_auth(username, password)
+ ActionController::HttpAuthentication::Basic.encode_credentials(username, password)
+ end
+end
diff --git a/spec/lib/api/helpers/pagination_spec.rb b/spec/lib/api/helpers/pagination_spec.rb
index 796c753d6c4..a008c1adeac 100644
--- a/spec/lib/api/helpers/pagination_spec.rb
+++ b/spec/lib/api/helpers/pagination_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Helpers::Pagination do
+RSpec.describe API::Helpers::Pagination do
subject { Class.new.include(described_class).new }
let(:paginator) { double('paginator') }
diff --git a/spec/lib/api/helpers/pagination_strategies_spec.rb b/spec/lib/api/helpers/pagination_strategies_spec.rb
index eaa71159714..e8a4243b407 100644
--- a/spec/lib/api/helpers/pagination_strategies_spec.rb
+++ b/spec/lib/api/helpers/pagination_strategies_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Helpers::PaginationStrategies do
+RSpec.describe API::Helpers::PaginationStrategies do
subject { Class.new.include(described_class).new }
let(:expected_result) { double("result") }
diff --git a/spec/lib/api/helpers/related_resources_helpers_spec.rb b/spec/lib/api/helpers/related_resources_helpers_spec.rb
index eeeb22abd10..a0dc69536b4 100644
--- a/spec/lib/api/helpers/related_resources_helpers_spec.rb
+++ b/spec/lib/api/helpers/related_resources_helpers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Helpers::RelatedResourcesHelpers do
+RSpec.describe API::Helpers::RelatedResourcesHelpers do
subject(:helpers) do
Class.new.include(described_class).new
end
diff --git a/spec/lib/api/helpers/version_spec.rb b/spec/lib/api/helpers/version_spec.rb
index a9f33962537..a87a3c5a026 100644
--- a/spec/lib/api/helpers/version_spec.rb
+++ b/spec/lib/api/helpers/version_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Helpers::Version do
+RSpec.describe API::Helpers::Version do
describe '.new' do
it 'is possible to initialize it with existing API version' do
expect(described_class.new('v4').to_s).to eq 'v4'
diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb
index 3595d06a184..8cba1e0794a 100644
--- a/spec/lib/api/helpers_spec.rb
+++ b/spec/lib/api/helpers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Helpers do
+RSpec.describe API::Helpers do
subject { Class.new.include(described_class).new }
describe '#find_project' do
diff --git a/spec/lib/api/support/git_access_actor_spec.rb b/spec/lib/api/support/git_access_actor_spec.rb
index 69637947c79..70753856419 100644
--- a/spec/lib/api/support/git_access_actor_spec.rb
+++ b/spec/lib/api/support/git_access_actor_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Support::GitAccessActor do
+RSpec.describe API::Support::GitAccessActor do
let(:user) { nil }
let(:key) { nil }
diff --git a/spec/lib/api/validations/validators/absence_spec.rb b/spec/lib/api/validations/validators/absence_spec.rb
index 31120979d4f..bfecaf4e243 100644
--- a/spec/lib/api/validations/validators/absence_spec.rb
+++ b/spec/lib/api/validations/validators/absence_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::Absence do
+RSpec.describe API::Validations::Validators::Absence do
include ApiValidatorsHelpers
subject do
diff --git a/spec/lib/api/validations/validators/array_none_any_spec.rb b/spec/lib/api/validations/validators/array_none_any_spec.rb
index 03f1c63b117..833adea6554 100644
--- a/spec/lib/api/validations/validators/array_none_any_spec.rb
+++ b/spec/lib/api/validations/validators/array_none_any_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::ArrayNoneAny do
+RSpec.describe API::Validations::Validators::ArrayNoneAny do
include ApiValidatorsHelpers
subject do
diff --git a/spec/lib/api/validations/validators/file_path_spec.rb b/spec/lib/api/validations/validators/file_path_spec.rb
index 8679f102d23..2c79260b8d5 100644
--- a/spec/lib/api/validations/validators/file_path_spec.rb
+++ b/spec/lib/api/validations/validators/file_path_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::FilePath do
+RSpec.describe API::Validations::Validators::FilePath do
include ApiValidatorsHelpers
subject do
diff --git a/spec/lib/api/validations/validators/git_ref_spec.rb b/spec/lib/api/validations/validators/git_ref_spec.rb
index 84de6272fe1..0d2d9e8f39a 100644
--- a/spec/lib/api/validations/validators/git_ref_spec.rb
+++ b/spec/lib/api/validations/validators/git_ref_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::GitRef do
+RSpec.describe API::Validations::Validators::GitRef do
include ApiValidatorsHelpers
subject do
diff --git a/spec/lib/api/validations/validators/git_sha_spec.rb b/spec/lib/api/validations/validators/git_sha_spec.rb
index 39c2fe1dcf9..ae6be52a4c7 100644
--- a/spec/lib/api/validations/validators/git_sha_spec.rb
+++ b/spec/lib/api/validations/validators/git_sha_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::GitSha do
+RSpec.describe API::Validations::Validators::GitSha do
include ApiValidatorsHelpers
let(:sha) { RepoHelpers.sample_commit.id }
diff --git a/spec/lib/api/validations/validators/integer_none_any_spec.rb b/spec/lib/api/validations/validators/integer_none_any_spec.rb
index a42f69fd96e..33fa7688d18 100644
--- a/spec/lib/api/validations/validators/integer_none_any_spec.rb
+++ b/spec/lib/api/validations/validators/integer_none_any_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::IntegerNoneAny do
+RSpec.describe API::Validations::Validators::IntegerNoneAny do
include ApiValidatorsHelpers
subject do
diff --git a/spec/lib/api/validations/validators/limit_spec.rb b/spec/lib/api/validations/validators/limit_spec.rb
index 600f74e1fb2..d71dde470cc 100644
--- a/spec/lib/api/validations/validators/limit_spec.rb
+++ b/spec/lib/api/validations/validators/limit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::Limit do
+RSpec.describe API::Validations::Validators::Limit do
include ApiValidatorsHelpers
subject do
diff --git a/spec/lib/api/validations/validators/untrusted_regexp_spec.rb b/spec/lib/api/validations/validators/untrusted_regexp_spec.rb
index 491bf94fd79..def67c94de0 100644
--- a/spec/lib/api/validations/validators/untrusted_regexp_spec.rb
+++ b/spec/lib/api/validations/validators/untrusted_regexp_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe API::Validations::Validators::UntrustedRegexp do
+RSpec.describe API::Validations::Validators::UntrustedRegexp do
include ApiValidatorsHelpers
subject do