2019-10-12 21:52:04 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe API::Helpers do
|
|
|
|
subject { Class.new.include(described_class).new }
|
|
|
|
|
2018-05-09 12:01:36 +05:30
|
|
|
describe '#find_project' do
|
|
|
|
let(:project) { create(:project) }
|
|
|
|
|
|
|
|
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.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 }
|
2020-04-22 19:07:51 +05:30
|
|
|
let(:non_existing_id) { non_existing_record_id }
|
2018-05-09 12:01:36 +05:30
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
subject.find_project(non_existing_id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
describe '#find_namespace' do
|
|
|
|
let(:namespace) { create(:namespace) }
|
|
|
|
|
|
|
|
shared_examples 'namespace finder' do
|
|
|
|
context 'when namespace exists' do
|
|
|
|
it 'returns requested namespace' do
|
|
|
|
expect(subject.find_namespace(existing_id)).to eq(namespace)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when namespace doesn't exists" do
|
|
|
|
it 'returns nil' do
|
|
|
|
expect(subject.find_namespace(non_existing_id)).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when ID is used as an argument' do
|
|
|
|
let(:existing_id) { namespace.id }
|
2020-04-22 19:07:51 +05:30
|
|
|
let(:non_existing_id) { non_existing_record_id }
|
2018-03-17 18:26:18 +05:30
|
|
|
|
|
|
|
it_behaves_like 'namespace finder'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when PATH is used as an argument' do
|
|
|
|
let(:existing_id) { namespace.path }
|
|
|
|
let(:non_existing_id) { 'non-existing-path' }
|
|
|
|
|
|
|
|
it_behaves_like 'namespace finder'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'user namespace finder' do
|
|
|
|
let(:user1) { create(:user) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(subject).to receive(:current_user).and_return(user1)
|
|
|
|
allow(subject).to receive(:header).and_return(nil)
|
|
|
|
allow(subject).to receive(:not_found!).and_raise('404 Namespace not found')
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when namespace is group' do
|
|
|
|
let(:namespace) { create(:group) }
|
|
|
|
|
|
|
|
context 'when user has access to group' do
|
|
|
|
before do
|
|
|
|
namespace.add_guest(user1)
|
|
|
|
namespace.save!
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns requested namespace' do
|
|
|
|
expect(namespace_finder).to eq(namespace)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when user doesn't have access to group" do
|
|
|
|
it 'raises not found error' do
|
|
|
|
expect { namespace_finder }.to raise_error(RuntimeError, '404 Namespace not found')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when namespace is user's personal namespace" do
|
|
|
|
let(:namespace) { create(:namespace) }
|
|
|
|
|
|
|
|
context 'when user owns the namespace' do
|
|
|
|
before do
|
|
|
|
namespace.owner = user1
|
|
|
|
namespace.save!
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns requested namespace' do
|
|
|
|
expect(namespace_finder).to eq(namespace)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when user doesn't own the namespace" do
|
|
|
|
it 'raises not found error' do
|
|
|
|
expect { namespace_finder }.to raise_error(RuntimeError, '404 Namespace not found')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#find_namespace!' do
|
|
|
|
let(:namespace_finder) do
|
|
|
|
subject.find_namespace!(namespace.id)
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'user namespace finder'
|
|
|
|
end
|
|
|
|
|
2019-02-15 15:39:39 +05:30
|
|
|
describe '#send_git_blob' do
|
2019-03-02 22:35:43 +05:30
|
|
|
let(:repository) { double }
|
|
|
|
let(:blob) { double(name: 'foobar') }
|
2019-02-15 15:39:39 +05:30
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
let(:send_git_blob) do
|
|
|
|
subject.send(:send_git_blob, repository, blob)
|
|
|
|
end
|
2019-02-15 15:39:39 +05:30
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
before do
|
|
|
|
allow(subject).to receive(:env).and_return({})
|
|
|
|
allow(subject).to receive(:content_type)
|
|
|
|
allow(subject).to receive(:header).and_return({})
|
|
|
|
allow(Gitlab::Workhorse).to receive(:send_git_blob)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets Gitlab::Workhorse::DETECT_HEADER header' do
|
|
|
|
expect(send_git_blob[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
|
|
|
|
end
|
2019-02-15 15:39:39 +05:30
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
context 'content disposition' do
|
2019-02-15 15:39:39 +05:30
|
|
|
context 'when blob name is null' do
|
|
|
|
let(:blob) { double(name: nil) }
|
|
|
|
|
|
|
|
it 'returns only the disposition' do
|
2019-03-02 22:35:43 +05:30
|
|
|
expect(send_git_blob['Content-Disposition']).to eq 'inline'
|
2019-02-15 15:39:39 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when blob name is not null' do
|
|
|
|
it 'returns disposition with the blob name' do
|
2019-03-02 22:35:43 +05:30
|
|
|
expect(send_git_blob['Content-Disposition']).to eq %q(inline; filename="foobar"; filename*=UTF-8''foobar)
|
2019-02-15 15:39:39 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-12-26 22:10:19 +05:30
|
|
|
|
|
|
|
describe '#track_event' do
|
|
|
|
it "creates a gitlab tracking event" do
|
|
|
|
expect(Gitlab::Tracking).to receive(:event).with('foo', 'my_event', {})
|
|
|
|
|
|
|
|
subject.track_event('my_event', category: 'foo')
|
|
|
|
end
|
|
|
|
|
|
|
|
it "logs an exception" do
|
|
|
|
expect(Rails.logger).to receive(:warn).with(/Tracking event failed/)
|
|
|
|
|
|
|
|
subject.track_event('my_event', category: nil)
|
|
|
|
end
|
|
|
|
end
|
2020-03-13 15:44:24 +05:30
|
|
|
|
|
|
|
describe '#order_options_with_tie_breaker' do
|
|
|
|
subject { Class.new.include(described_class).new.order_options_with_tie_breaker }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow_any_instance_of(described_class).to receive(:params).and_return(params)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with non-id order given' do
|
|
|
|
context 'with ascending order' do
|
|
|
|
let(:params) { { order_by: 'name', sort: 'asc' } }
|
|
|
|
|
|
|
|
it 'adds id based ordering with same direction as primary order' do
|
|
|
|
is_expected.to eq({ 'name' => 'asc', 'id' => 'asc' })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with descending order' do
|
|
|
|
let(:params) { { order_by: 'name', sort: 'desc' } }
|
|
|
|
|
|
|
|
it 'adds id based ordering with same direction as primary order' do
|
|
|
|
is_expected.to eq({ 'name' => 'desc', 'id' => 'desc' })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with non-id order but no direction given' do
|
|
|
|
let(:params) { { order_by: 'name' } }
|
|
|
|
|
|
|
|
it 'adds ID ASC order' do
|
|
|
|
is_expected.to eq({ 'name' => nil, 'id' => 'asc' })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with id order given' do
|
|
|
|
let(:params) { { order_by: 'id', sort: 'asc' } }
|
|
|
|
|
|
|
|
it 'does not add an additional order' do
|
|
|
|
is_expected.to eq({ 'id' => 'asc' })
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-03-17 18:26:18 +05:30
|
|
|
end
|