2019-11-13 19:06:24 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2019-04-09 11:38:58 -04:00
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache do
|
|
|
|
subject(:access) { described_class.new(build(:user), 'dummy_label') }
|
|
|
|
|
|
|
|
describe '#loaded?' do
|
|
|
|
it 'is `true` when it was loaded recently' do
|
|
|
|
Timecop.freeze do
|
|
|
|
allow(access).to receive(:loaded_at).and_return(5.minutes.ago)
|
|
|
|
|
|
|
|
expect(access).to be_loaded
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is `false` when there is no loading time' do
|
|
|
|
expect(access).not_to be_loaded
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is `false` when there the result was loaded a long time ago' do
|
|
|
|
Timecop.freeze do
|
|
|
|
allow(access).to receive(:loaded_at).and_return(2.weeks.ago)
|
|
|
|
|
|
|
|
expect(access).not_to be_loaded
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe 'load!' do
|
|
|
|
let(:fake_client) { double('ExternalAuthorization::Client') }
|
|
|
|
let(:fake_response) do
|
|
|
|
double(
|
|
|
|
'Response',
|
|
|
|
'successful?' => true,
|
|
|
|
'valid?' => true,
|
|
|
|
'reason' => nil
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(access).to receive(:load_from_cache)
|
|
|
|
allow(fake_client).to receive(:request_access).and_return(fake_response)
|
|
|
|
allow(Gitlab::ExternalAuthorization::Client).to receive(:new) { fake_client }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when loading from the webservice' do
|
|
|
|
it 'loads from the webservice it the cache was empty' do
|
|
|
|
expect(access).to receive(:load_from_cache)
|
|
|
|
expect(access).to receive(:load_from_service).and_call_original
|
|
|
|
|
|
|
|
access.load!
|
|
|
|
|
|
|
|
expect(access).to be_loaded
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'assigns the accessibility, reason and loaded_at' do
|
|
|
|
allow(fake_response).to receive(:successful?).and_return(false)
|
|
|
|
allow(fake_response).to receive(:reason).and_return('Inaccessible label')
|
|
|
|
|
|
|
|
access.load!
|
|
|
|
|
|
|
|
expect(access.reason).to eq('Inaccessible label')
|
|
|
|
expect(access).not_to have_access
|
|
|
|
expect(access.loaded_at).not_to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns itself' do
|
|
|
|
expect(access.load!).to eq(access)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'stores the result in redis' do
|
|
|
|
Timecop.freeze do
|
|
|
|
fake_cache = double
|
|
|
|
expect(fake_cache).to receive(:store).with(true, nil, Time.now)
|
|
|
|
expect(access).to receive(:cache).and_return(fake_cache)
|
|
|
|
|
|
|
|
access.load!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the request fails' do
|
|
|
|
before do
|
|
|
|
allow(fake_client).to receive(:request_access) do
|
|
|
|
raise ::Gitlab::ExternalAuthorization::RequestFailed.new('Service unavailable')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'is loaded' do
|
|
|
|
access.load!
|
|
|
|
|
|
|
|
expect(access).to be_loaded
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'assigns the correct accessibility, reason and loaded_at' do
|
|
|
|
access.load!
|
|
|
|
|
|
|
|
expect(access.reason).to eq('Service unavailable')
|
|
|
|
expect(access).not_to have_access
|
|
|
|
expect(access.loaded_at).not_to be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not store the result in redis' do
|
|
|
|
fake_cache = double
|
|
|
|
expect(fake_cache).not_to receive(:store)
|
|
|
|
allow(access).to receive(:cache).and_return(fake_cache)
|
|
|
|
|
|
|
|
access.load!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'When loading from cache' do
|
|
|
|
let(:fake_cache) { double('ExternalAuthorization::Cache') }
|
|
|
|
|
|
|
|
before do
|
|
|
|
allow(access).to receive(:cache).and_return(fake_cache)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not load from the webservice' do
|
|
|
|
Timecop.freeze do
|
|
|
|
expect(fake_cache).to receive(:load).and_return([true, nil, Time.now])
|
|
|
|
|
|
|
|
expect(access).to receive(:load_from_cache).and_call_original
|
|
|
|
expect(access).not_to receive(:load_from_service)
|
|
|
|
|
|
|
|
access.load!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'loads from the webservice when the cached result was too old' do
|
|
|
|
Timecop.freeze do
|
|
|
|
expect(fake_cache).to receive(:load).and_return([true, nil, 2.days.ago])
|
|
|
|
|
|
|
|
expect(access).to receive(:load_from_cache).and_call_original
|
|
|
|
expect(access).to receive(:load_from_service).and_call_original
|
|
|
|
allow(fake_cache).to receive(:store)
|
|
|
|
|
|
|
|
access.load!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|