Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/api')
-rw-r--r--spec/lib/api/entities/bulk_imports/export_status_spec.rb20
-rw-r--r--spec/lib/api/entities/release_spec.rb39
-rw-r--r--spec/lib/api/helpers/caching_spec.rb160
-rw-r--r--spec/lib/api/helpers/related_resources_helpers_spec.rb6
-rw-r--r--spec/lib/api/helpers_spec.rb98
5 files changed, 297 insertions, 26 deletions
diff --git a/spec/lib/api/entities/bulk_imports/export_status_spec.rb b/spec/lib/api/entities/bulk_imports/export_status_spec.rb
new file mode 100644
index 00000000000..7d79e372027
--- /dev/null
+++ b/spec/lib/api/entities/bulk_imports/export_status_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::BulkImports::ExportStatus do
+ let_it_be(:export) { create(:bulk_import_export) }
+
+ let(:entity) { described_class.new(export, request: double) }
+
+ subject { entity.as_json }
+
+ it 'has the correct attributes' do
+ expect(subject).to eq({
+ relation: export.relation,
+ status: export.status,
+ error: export.error,
+ updated_at: export.updated_at
+ })
+ end
+end
diff --git a/spec/lib/api/entities/release_spec.rb b/spec/lib/api/entities/release_spec.rb
index 06062634015..4f40830a15c 100644
--- a/spec/lib/api/entities/release_spec.rb
+++ b/spec/lib/api/entities/release_spec.rb
@@ -54,18 +54,41 @@ RSpec.describe API::Entities::Release do
subject(:description_html) { entity.as_json['description_html'] }
- it 'renders special references if current user has access' do
- project.add_reporter(user)
+ it 'is inexistent' do
+ expect(description_html).to be_nil
+ end
+
+ context 'when remove_description_html_in_release_api feature flag is disabled' do
+ before do
+ stub_feature_flags(remove_description_html_in_release_api: false)
+ end
+
+ it 'renders special references if current user has access' do
+ project.add_reporter(user)
+
+ expect(description_html).to include(issue_path)
+ expect(description_html).to include(issue_title)
+ end
- expect(description_html).to include(issue_path)
- expect(description_html).to include(issue_title)
+ it 'does not render special references if current user has no access' do
+ project.add_guest(user)
+
+ expect(description_html).not_to include(issue_path)
+ expect(description_html).not_to include(issue_title)
+ end
end
- it 'does not render special references if current user has no access' do
- project.add_guest(user)
+ context 'when remove_description_html_in_release_api_override feature flag is enabled' do
+ before do
+ stub_feature_flags(remove_description_html_in_release_api_override: project)
+ end
- expect(description_html).not_to include(issue_path)
- expect(description_html).not_to include(issue_title)
+ it 'renders special references if current user has access' do
+ project.add_reporter(user)
+
+ expect(description_html).to include(issue_path)
+ expect(description_html).to include(issue_title)
+ end
end
end
end
diff --git a/spec/lib/api/helpers/caching_spec.rb b/spec/lib/api/helpers/caching_spec.rb
index a8cd061e123..f94c44c7382 100644
--- a/spec/lib/api/helpers/caching_spec.rb
+++ b/spec/lib/api/helpers/caching_spec.rb
@@ -2,34 +2,46 @@
require "spec_helper"
-RSpec.describe API::Helpers::Caching do
+RSpec.describe API::Helpers::Caching, :use_clean_rails_redis_caching do
subject(:instance) { Class.new.include(described_class).new }
- describe "#present_cached" do
- let_it_be(:project) { create(:project) }
- let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
- let(:presenter) { API::Entities::Todo }
+ let(:presenter) { API::Entities::Todo }
- let(:kwargs) do
- {
- with: presenter,
- project: project
- }
+ let(:return_value) do
+ {
+ foo: "bar"
+ }
+ end
+
+ let(:kwargs) do
+ {
+ expires_in: 1.minute
+ }
+ end
+
+ before do
+ # We have to stub #body as it's a Grape method
+ # unavailable in the module by itself
+ allow(instance).to receive(:body) do |data|
+ data
end
+ allow(instance).to receive(:current_user) { user }
+ end
+
+ describe "#present_cached" do
subject do
instance.present_cached(presentable, **kwargs)
end
- before do
- # We have to stub #body as it's a Grape method
- # unavailable in the module by itself
- expect(instance).to receive(:body) do |data|
- data
- end
-
- allow(instance).to receive(:current_user) { user }
+ let(:kwargs) do
+ {
+ with: presenter,
+ project: project
+ }
end
context "single object" do
@@ -136,4 +148,116 @@ RSpec.describe API::Helpers::Caching do
end
end
end
+
+ describe "#cache_action" do
+ def perform
+ instance.cache_action(cache_key, **kwargs) do
+ expensive_thing.do_very_expensive_action
+ end
+ end
+
+ subject { perform }
+
+ let(:expensive_thing) { double(do_very_expensive_action: return_value) }
+ let(:cache_key) do
+ [user, :foo]
+ end
+
+ it { is_expected.to be_a(Gitlab::Json::PrecompiledJson) }
+
+ it "represents the correct data" do
+ expect(subject.to_s).to eq(Gitlab::Json.dump(return_value).to_s)
+ end
+
+ it "only calls the expensive action once" do
+ expected_kwargs = described_class::DEFAULT_CACHE_OPTIONS.merge(kwargs)
+
+ expect(expensive_thing).to receive(:do_very_expensive_action).once
+ expect(instance.cache).to receive(:fetch).with(cache_key, **expected_kwargs).exactly(5).times.and_call_original
+
+ 5.times { perform }
+ end
+
+ it "handles nested cache calls" do
+ nested_call = instance.cache_action(cache_key, **kwargs) do
+ instance.cache_action([:nested], **kwargs) do
+ expensive_thing.do_very_expensive_action
+ end
+ end
+
+ expect(nested_call.to_s).to eq(subject.to_s)
+ end
+ end
+
+ describe "#cache_action_if" do
+ subject do
+ instance.cache_action_if(conditional, cache_key, **kwargs) do
+ return_value
+ end
+ end
+
+ let(:cache_key) do
+ [user, :conditional_if]
+ end
+
+ context "conditional is truthy" do
+ let(:conditional) { "truthy thing" }
+
+ it { is_expected.to be_a(Gitlab::Json::PrecompiledJson) }
+
+ it "caches the block" do
+ expect(instance).to receive(:cache_action).with(cache_key, **kwargs)
+
+ subject
+ end
+ end
+
+ context "conditional is falsey" do
+ let(:conditional) { false }
+
+ it { is_expected.to eq(return_value) }
+
+ it "doesn't cache the block" do
+ expect(instance).not_to receive(:cache_action).with(cache_key, **kwargs)
+
+ subject
+ end
+ end
+ end
+
+ describe "#cache_action_unless" do
+ subject do
+ instance.cache_action_unless(conditional, cache_key, **kwargs) do
+ return_value
+ end
+ end
+
+ let(:cache_key) do
+ [user, :conditional_unless]
+ end
+
+ context "conditional is truthy" do
+ let(:conditional) { "truthy thing" }
+
+ it { is_expected.to eq(return_value) }
+
+ it "doesn't cache the block" do
+ expect(instance).not_to receive(:cache_action).with(cache_key, **kwargs)
+
+ subject
+ end
+ end
+
+ context "conditional is falsey" do
+ let(:conditional) { false }
+
+ it { is_expected.to be_a(Gitlab::Json::PrecompiledJson) }
+
+ it "caches the block" do
+ expect(instance).to receive(:cache_action).with(cache_key, **kwargs)
+
+ subject
+ end
+ end
+ end
end
diff --git a/spec/lib/api/helpers/related_resources_helpers_spec.rb b/spec/lib/api/helpers/related_resources_helpers_spec.rb
index a0dc69536b4..8b2e95c0434 100644
--- a/spec/lib/api/helpers/related_resources_helpers_spec.rb
+++ b/spec/lib/api/helpers/related_resources_helpers_spec.rb
@@ -63,6 +63,12 @@ RSpec.describe API::Helpers::RelatedResourcesHelpers do
is_expected.to start_with('https://')
end
+ it 'accepts the host if it contains an underscore' do
+ stub_default_url_options(host: 'w_ww.example.com')
+
+ is_expected.to start_with('http://w_ww.example.com/')
+ end
+
it 'accepts port to be nil' do
stub_default_url_options(port: nil)
diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb
index 15b22fcf25e..87cd0d4388c 100644
--- a/spec/lib/api/helpers_spec.rb
+++ b/spec/lib/api/helpers_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe API::Helpers do
+ using RSpec::Parameterized::TableSyntax
+
subject { Class.new.include(described_class).new }
describe '#find_project' do
@@ -99,6 +101,59 @@ RSpec.describe API::Helpers do
end
end
+ describe '#find_project!' do
+ let_it_be(:project) { create(:project) }
+
+ let(:user) { project.owner}
+
+ before do
+ allow(subject).to receive(:current_user).and_return(user)
+ allow(subject).to receive(:authorized_project_scope?).and_return(true)
+ allow(subject).to receive(:job_token_authentication?).and_return(false)
+ allow(subject).to receive(:authenticate_non_public?).and_return(false)
+ end
+
+ shared_examples 'project finder' do
+ context 'when project exists' do
+ it 'returns requested project' do
+ expect(subject.find_project!(existing_id)).to eq(project)
+ end
+
+ it 'returns nil' do
+ expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
+ expect(subject.find_project!(non_existing_id)).to be_nil
+ end
+ end
+ end
+
+ context 'when ID is used as an argument' do
+ let(:existing_id) { project.id }
+ let(:non_existing_id) { non_existing_record_id }
+
+ it_behaves_like 'project finder'
+ end
+
+ context 'when PATH is used as an argument' do
+ let(:existing_id) { project.full_path }
+ let(:non_existing_id) { 'something/else' }
+
+ it_behaves_like 'project finder'
+
+ context 'with an invalid PATH' do
+ let(:non_existing_id) { 'undefined' } # path without slash
+
+ it_behaves_like 'project finder'
+
+ it 'does not hit the database' do
+ expect(Project).not_to receive(:find_by_full_path)
+ expect(subject).to receive(:render_api_error!).with('404 Project Not Found', 404)
+
+ subject.find_project!(non_existing_id)
+ end
+ end
+ end
+ end
+
describe '#find_namespace' do
let(:namespace) { create(:namespace) }
@@ -191,6 +246,49 @@ RSpec.describe API::Helpers do
it_behaves_like 'user namespace finder'
end
+ describe '#authorized_project_scope?' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:other_project) { create(:project) }
+ let_it_be(:job) { create(:ci_build) }
+
+ let(:send_authorized_project_scope) { subject.authorized_project_scope?(project) }
+
+ where(:job_token_authentication, :route_setting, :feature_flag, :same_job_project, :expected_result) do
+ false | false | false | false | true
+ false | false | false | true | true
+ false | false | true | false | true
+ false | false | true | true | true
+ false | true | false | false | true
+ false | true | false | true | true
+ false | true | true | false | true
+ false | true | true | true | true
+ true | false | false | false | true
+ true | false | false | true | true
+ true | false | true | false | true
+ true | false | true | true | true
+ true | true | false | false | false
+ true | true | false | true | false
+ true | true | true | false | false
+ true | true | true | true | true
+ end
+
+ with_them do
+ before do
+ allow(subject).to receive(:job_token_authentication?).and_return(job_token_authentication)
+ allow(subject).to receive(:route_authentication_setting).and_return(job_token_scope: route_setting ? :project : nil)
+ allow(subject).to receive(:current_authenticated_job).and_return(job)
+ allow(job).to receive(:project).and_return(same_job_project ? project : other_project)
+
+ stub_feature_flags(ci_job_token_scope: false)
+ stub_feature_flags(ci_job_token_scope: project) if feature_flag
+ end
+
+ it 'returns the expected result' do
+ expect(send_authorized_project_scope).to eq(expected_result)
+ end
+ end
+ end
+
describe '#send_git_blob' do
let(:repository) { double }
let(:blob) { double(name: 'foobar') }