145 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| require 'spec_helper'
 | |
| 
 | |
| RSpec.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
 |